2015-01-17 2 views
4

Прошу прощения, этот вопрос получился немного длинным, но я работал над этим в течение некоторого времени и действительно нуждался в объяснении всей истории.Passport.js, Express.js и Angular.js routing: как они могут сосуществовать?

фон: App на основе стека MEAN, пытаясь разрешить логинов Facebook с помощью Passport.js.

После Passport.js guide я осуществил что-то похожее на:

// HTML 
    <a href="/connect/facebook" target="_self">Add a Facebook login</a> 
// send to facebook to do the authentication 
app.get('/connect/facebook',isLoggedIn, passport.authorize('facebook', 
    { scope : 'email' }) 
); 
// handle the callback after facebook has authorized the user 
app.get('/connect/facebook/callback', 
    passport.authorize('facebook', { 
    successRedirect : '/profile', 
    failureRedirect : '/profile' 
    })); 

Обратите внимание на target=_self в HTML, чтобы пропустить Угловое маршрутизации. Очевидно, что авторизация работает нормально. Однако перенаправление не работает, так как маршрутизация обрабатывается угловым. После авторизации я никогда не приземляюсь на /profile (но по Угловому маршруту по умолчанию).

Поэтому я пробовал с пользовательским обратным вызовом, как это было предложено Passport.js here, с надеждой передать данные json в Angular и позволить Angular выполнять маршрутизацию. Я закончил что-то вроде:

// In the controller 
$http.get("/connect/facebook").success(function(data){ 
    // here I wait for json data from the server and do the routing 
}); 
// I call this route from Angular 
app.get('/connect/facebook',isLoggedIn,passport.authorize('facebook', 
    { scope : 'email' }) 
); 
// But Facebook lands here! 
app.get('/connect/facebook/callback',function(req, res, next) { 
    passport.authorize('facebook', function(err, user, info) { 
     res.json({something:smtg}); 
     ... 

Очевидно, пользовательские обратные вызовы работают для локального входа, как объясняет Passport.js. Но вот вы видите проблему? Я звоню /connect/facebook из Angular, но я должен получить json от /connect/facebook/callback.

Я собираюсь отказаться от паспорта, но до этого вы видите какое-либо решение, которое позволит посадку на /profile после авторизации FB, возможно, с помощью специального сообщения? Большое спасибо за чтение.

EDIT: Тот же вопрос был сообщен как вопрос о Passport-Facebook GitHub account. Некоторые дополнительные попытки были опубликованы там, но не совсем исправлены.

+0

Как это Перенаправление перехвачены Угловая? У вас есть маршрут '/ profile ', определенный в вашем приложении Express? Что он служит? – laggingreflex

+0

У меня есть маршрут '/ profile' в режиме Angular, no'/profile' в Express и 'app.get ('*', ..)' route в Express. Он служит маршруту по умолчанию в угловом: '.otherwise ({redirectTo: '/'});'. Любая попытка использовать 'res.render' или' res.redirect (в определенном угловом виде) 'из Express является напрасной. – ZzKr

ответ

4

Это немного больше, чем описано в одном ответе, но я попытаюсь начать указывать вас в правильном направлении.

По сути, маршруты Angular.js на самом деле не являются HTML-маршрутами, а внутренней структурой маршрутов, которая использует URL-адрес для использования конечным пользователем. Помните, что Angular.js является клиентским скриптом и что полная загрузка страницы нежелательна, так как это перезагрузит весь скрипт. Поэтому /# используется для трюк браузер переходит в конкретный бит кода в уже загруженном скрипте. (в отличие от традиционного местоположения привязки в документе HTML). К сожалению (или, к счастью), режим HTML 5 позволяет скрыть часть URL-адреса /#, поэтому вместо http://somesite.com/#/someroute вы видите только http://somesite.com/someroute. Будьте уверены, однако, что /# все еще существует. Angular.js использует HTML5 pushState (AKA HistoryAPI) для выполнения магической замены.

Учитывая это, если вы назвали маршрут сервера, вы находитесь за пределами скрипта Angular.js, и любой вызов для загрузки углового сценария снова начнется с самого начала. Вы не можете называть свой маршрут Angular.js с сервера без полной перезагрузки. Таким образом, вы действительно выполняете перенаправление двойного маршрута здесь. Ваш сервер должен вызывать маршрут по умолчанию для углового, добавляя /#/someroute к вызову. Страница angular.js загрузится, проанализируйте /# и перенаправляйте на правильный угловой маршрут. Однако имейте в виду, что если какая-либо зависимость от уже загруженных объектов, они больше не находятся в памяти.Поэтому любой маршрут, к которому обращается этот путь, должен работать так, как если бы он был точкой входа в ваше приложение.

Фактически, вы должны попробовать использовать successRedirect : '#/profile', имея в виду, что маршрут profile в угловой должен рассматриваться как точка входа в приложение.

Надеюсь, вам это поможет.

+0

Спасибо за подробный ответ. Я пробовал то, что вы предложили, т. Е. Используя '#/profile', но с небольшой удачей. Я заметил из регистратора на сервере, что маршрут '/ profile' (или' #/profile') не вызывается. Я сомневался, что у Express нет такого маршрута, поэтому я реализовал простой маршрут 'app.get ('/ profile', function (req, res) {res.render (некоторая html-страница);}'. Также в этот случай не повезло. – ZzKr

+0

плюс один для ссылки на pushState api. не знал, как маршрутизация работала в угловой! –

0

Если метод Клайва не работает, возможно ли, что вы не избавились от фрагмента фрагмента из обратного вызова facebook. # =.

Есть Распознать this post

+0

Всегда указывайте наиболее релевантную часть важной ссылки, если целевой сайт недоступен или постоянно находится в автономном режиме. ваш ответ прочитал это http://stackoverflow.com/help/how-to-answer – davejal

+0

Спасибо человеку. –

Смежные вопросы