5

我很抱歉这个问题有点长,但我已经研究了一段时间,真的需要解释所有的故事。

背景:基于 MEAN 堆栈的应用程序,尝试使用 Passport.js授权Facebook 登录。

按照 Passport.js指南,我实现了类似于:

// 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=_selfhtml 中的 ,以便跳过 Angular 路由。显然,授权工作正常。但是,重定向不起作用,因为路由是由 Angular 处理的。授权后,我从未登陆/profile(但在默认的 Angular 路线上)。

因此,我尝试使用 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 打来电话,但我应该从/connect/facebook/callback.

我即将放弃 Passport,但在此之前,您是否看到任何允许/profile在 FB 授权后登陆的解决方案,也许带有自定义消息?非常感谢您通读。

编辑:同样的问题已报告为Passport-Facebook GitHub 帐户上的问题。那里已经发布了一些额外的尝试,但还没有完全修复。

4

2 回答 2

5

这比一个答案中描述的要深入一些,但我会尝试开始为您指明正确的方向。

从本质上讲,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 脚本的调用都将从头开始。如果没有完全重新加载,您实际上无法从服务器调用 Angular.js 路由。因此,您实际上是在这里进行双路由重定向。您的服务器应该将其称为 Angular 的默认路由,并附/#/someroute加到调用中。angular.js 页面将加载、解析/#并重定向到正确的 angular 路径。但是请记住,如果对已加载的对象有任何依赖关系,则这些对象将不再在内存中。因此,以这种方式访问​​的任何路由都应该像应用程序的入口点一样运行。

实际上,您应该尝试使用successRedirect : '#/profile',请记住,profile角度中的路线应被视为应用程序入口点。

希望这能让你开始。

于 2015-01-17T18:21:00.123 回答
0

如果@Claies 的方式不起作用,您是否可能没有从 facebook 回调中删除 # =片段。

阅读这篇文章

于 2015-11-26T03:33:04.690 回答