SailsJS Linkedin OAuth 2.0登录流程问题

时间:2015-08-01 17:39:28

标签: node.js oauth-2.0 sails.js linkedin

我正在尝试使用此库来验证使用Linkedin:

https://github.com/auth0/passport-linkedin-oauth2

没有Linkedin登录提示

我已经配置了我的Passport Linkedin策略:

var passport = require('passport');
var LinkedInStrategy = require('passport-linkedin-oauth2').Strategy;

passport.serializeUser(function(user, done) {
  done(null, user.id);
});

passport.deserializeUser(function(id, done) {
  User.findById(id, function (err, user) {
    done(err, user);
  });
});

passport.use(new LinkedInStrategy({
  clientID: 'LINKEDIN_API_KEY',
  clientSecret: 'LINKEDIN_API_SECRET',
  callbackURL: 'http://localhost:1337/auth/linkedin/callback',
  scope: ['r_emailaddress', 'r_basicprofile'],
  state: true
}, function(accessToken, refreshToken, profile, done) {
  // asynchronous verification, for effect... 
  process.nextTick(function () {
    // To keep the example simple, the user's LinkedIn profile is returned to 
    // represent the logged-in user. In a typical application, you would want 
    // to associate the LinkedIn account with a user record in your database, 
    // and return that user instead. 
    return done(null, profile);
  });
}));

我的AuthController.js看起来像这样:

var passport = require('passport');

module.exports = {

    login: function(req, res) {     
        passport.authenticate('linkedin', function(err, user, info) {
            // The request will be redirected to LinkedIn for authentication, so this 
            // function will not be called. 
        });
    },

    callback: function(req, res) {

        // ------------------------------------------------------------------------
        // after user authenticated, we get the user's email from
        // Linkedin's JSON response and save it against the matching  
        // email address in the User model
        // ------------------------------------------------------------------------
        console.log(res);
    },

    logout: function(req, res) {
        req.logout();
        res.send('logout successful');
    }   
};

从linkedin oauth库,我希望调用:

passport.authenticate('linkedin', function...);

在我的AuthController的登录操作中,要将用户重定向到Linkedin的登录提示页面,但我实际看到的是我的浏览器只是继续加载,加载,加载并且永不停止。

我做错了吗?

我不确定的一些问题:

  • 在整个事情开始工作之前,Linkedin是否希望我的服务器能够在HTTPS上运行?
  • 我的Linkedin开发者应用设置中是否需要进行一些特殊配置? (我已启用所有正确的Javascript SDK网址)

回叫错误

好的,继续,我的下一个问题似乎在这里:

return done(null, profile);
           ^
TypeError: object is not a function

我的代码遵循此处的npm模块说明:https://www.npmjs.com/package/passport-linkedin-oauth2

也许SailsJS还有另一种写作方式......

身份验证始终失败

在解决了我在下面的解决方案中提到的回调错误后,我决定继续前进,看看它是如何发生的,尽管Linkedin文档与我对NPM库的期望不完全匹配。

我的下一个问题是我的authenticated.js政策似乎总是失败。

我的代码如下:

// We use passport to determine if we're authenticated
module.exports = function (req, res, next) {
    if(req.authenticated) { // <---- this is the error line
        return next();
    }
    else
    {
        res.send(401, {
            error: 'Nice try buddy. Try logging in with Linkedin first :]'
        });
    }
};

2 个答案:

答案 0 :(得分:3)

无登录提示解决方案

叹息

我想我已经开始掌握SailsJS和纯ExpressJS代码之间的一些区别。

问题似乎是我在passport.authenticate()方法结束时遗漏了这段代码:

(req, res)

我再次查看本教程后选择了它:http://iliketomatoes.com/implement-passport-js-authentication-with-sails-js-0-10-2/

现在,最终的身份验证方法应如下所示:

passport.authenticate('linkedin', function(err, user, info) {



    // The request will be redirected to LinkedIn for authentication, so this 
    // function will not be called. 



})(req, res); // <--- notice this extra (req, res) code here

哪个与Passportjs文档相符:

passport.authenticate('local'),
  function(req, res) {
    // If this function gets called, authentication was successful.
    // `req.user` contains the authenticated user.
    res.redirect('/users/' + req.user.username);
  });

在某种程度上......如果你知道我的意思......:D

现在我按照预期获得了我的Linkedin登录提示。

最后!

回调错误解决方案

好的.....我不确定这是否完成了登录过程...但是......

我注意到我有一条额外的行:

passReqToCallback: true

取自此页面:

https://github.com/auth0/passport-linkedin-oauth2/issues/29

我删除了该错误消息。

我还将我的回调代码更改为:

passport.authenticate('linkedin', function(err, user, info) {

    res.json(200, {
        user: user
    });

})(req, res);

我的用户JSON似乎是我的Linkedin用户个人资料信息:

{
    user: {
        provider: "linkedin",
        ...
    }
}

但那......与Linkedin文档相矛盾......我没有看到任何我希望在Linkedin OAuth 2.0文档的第3步中看到的access_tokenexpire_in属性({{ {3}})...

所以......据说......我应该使用这个用户对象并针对现有用户对象创建/更新?

身份验证始终失败解决方案

好的,再过几天,我添加了额外的代码来生成用户实体(如果在我的数据库中找不到的话),否则只返回找到的用户。

这是最后一个问题,在我的policies文件夹中,我有一个authenticated.js,它看起来像这样:

// We use passport to determine if we're authenticated
module.exports = function (req, res, next) {
    if(req.authenticated) { // <---- this is the error line
        return next();
    }
    else
    {
        res.send(401, {
            error: 'Nice try buddy. Try logging in with Linkedin first :]'
        });
    }
};

对所有这些网络开发的新手,我想:

req.authenticated; // should call match name of the file ?

是正确的,但我正在学习本教程:

https://developer.linkedin.com/docs/oauth2

并且他命名了他的文件:isAuthenticated.js我认为这只是一个名字....但我错了:D

原来,正确的代码是:

req.isAuthenticated()

完整之后,正确的代码变为:

// We use passport to determine if we're authenticated
module.exports = function (req, res, next) {
    if(req.isAuthenticated()) { // alright, that's more like it!
        return next();
    }
    else
    {
        res.send(401, {
            error: 'Nice try buddy. Try logging in with Linkedin first :]'
        });
    }
};

也许isAuthenticated是一个Passportjs函数,而不仅仅是我最初想过的名字。

我的进一步研究表明,这个页面对我来说是这样的:

http://iliketomatoes.com/implement-passport-js-authentication-with-sails-js-0-10-2/

也许req.authenticated只能用于HTML电子邮件密码登录表单,如上面的Stackoverflow帖子所示,req.isAuthenticated()用于OAuth内容。

无论如何,我仍然不知道这是不是正确的路径,但到目前为止,我现在在我的应用程序中获得了身份验证,我可以访问受保护的资源。不知道我将登录多长时间,也许我还需要像Linkedin文档所说的那样每15分钟建立一次刷新令牌?

希望这有助于其他面临同样问题的Sailsjs用户:)

答案 1 :(得分:1)

  

Linkedin是否希望我的服务器在它允许之前在HTTPS上运行   整件事情开始起作用了吗?

没有。 API在本地http设置上也能正常工作。

  

我的Linkedin中是否需要进行一些特殊配置   开发者app设置? (我已经启用了所有正确的Javascript SDK   URL)的

不,你的设置很好。

浏览器一直在加载,因为在身份验证后,LinkedIn会重定向到您没有处理响应流的回调action

您需要在callback操作中处理响应。这样的事情会做:

callback: function(req, res) {
    passport.authenticate('linkedin', function(err, user){
        // handle error
        // do something with the user (register/login)
        return res.redirect('/home');
    });
}

我强烈建议您使用sails-generate-auth来维护第三方登录。非常容易设置和配置。您需要做的就是为不同的策略提供访问令牌和秘密(通过config/passport.js或者最好通过config/local.js)。将为您节省大量冗余代码。