我正在尝试使用此库来验证使用Linkedin:
https://github.com/auth0/passport-linkedin-oauth2
我已经配置了我的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的登录提示页面,但我实际看到的是我的浏览器只是继续加载,加载,加载并且永不停止。
我做错了吗?
我不确定的一些问题:
好的,继续,我的下一个问题似乎在这里:
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 :]'
});
}
};
答案 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_token
或expire_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
)。将为您节省大量冗余代码。