我在 Passport 中构建了一个登录系统并且运行得很好。现在,我想将 LinkedIn 登录集成到我的系统中。我已经有
clientID
、clientSecret
等需要登录。这是按下 LinkedIn 登录按钮时调用的代码。
passport.use('linkedin', new OAuth2Strategy({
authorizationURL: 'https://www.linkedin.com/uas/oauth2/authorization',
tokenURL: 'https://www.linkedin.com/uas/oauth2/accessToken',
clientID: clientid,
clientSecret: clientsecret,
callbackURL: '/linkedinLogin/linkedinCallbackUrlLogin',
passReqToCallback: true
},
function(req,accessToken, refreshToken, profile, done) {
console.log('authenticated');
console.log(accessToken);
req.session.code = accessToken;
process.nextTick(function () {
done(null, {
code : req.code
});
});
}));
回调函数中的两个
console.log()
调用都已成功触发,这意味着我已成功通过 LinkedIn 登录并收到了我的访问令牌。因此,我与 LinkedIn 连接的部分是正确的,我缺少的是我实际登录用户的部分。如您所见,callbackURL
指向/linkedinLogin/linkedinCallbackUrlLogin
。这就是我在那条路线中所做的:
app.get('/linkedinLogin/linkedinCallbackUrlLogin', passport.authenticate('linkedin', {
session: false,
successRedirect:'/linkedinLogin/success',
failureRedirect:'/linkedinLogin/fail'
}));
我只是指定一个
successRedirect
和一个failureRedirect
。请注意,如果我输入 session : true
,我会收到错误 Failed to serialize user into session
,所以现在我将其保留为 false。
successRedirect
调用成功。在该路线中,我向 LinkedIn 调用 GET
请求以访问有关用户的一些数据。我想将此数据存储在我的数据库中并记住登录的用户。我就是这样做的:
https.get(
{
host: 'api.linkedin.com' ,
path: '/v1/people/~?format=json' ,
port:443 ,
headers : {'Authorization': ' Bearer ' + req.session.code}
},
function(myres) {
myres.on("data", function(chunk) {
var linkedinJsonResult = JSON.parse(chunk);
User.findOne({linkedinLogin : linkedinJsonResult.id}, function(err, userSearchResult){
if(err) {
throw err;
}
//user found, login
if(userSearchResult){
console.log(userSearchResult);
}
else {
//create user
var newUser = new User(
{
url : linkedinJsonResult.siteStandardProfileRequest.url,
name : linkedinJsonResult.firstName + " " + linkedinJsonResult.lastName,
linkedinLogin : linkedinJsonResult.id,
regDate : new Date()
}
);
//save user
newUser.save(function(err, user){
if(err){
throw err;
}
//login
console.log(user);
});
}
});
});
}
);
让我解释一下那里的代码。获取用户的数据后,我检查收到的“id”字段。如果此 ID 与存储到数据库中的某个用户的
linkedinLogin
字段匹配,我认为它已经注册(已在数据库中找到该用户),因此我必须登录他/她。否则我只需创建一个新的用户使用从 GET
请求收到的数据。
我的问题是,在这两种情况下 - 在我的数据库中找到用户,或者必须创建用户 - 每当与我的网站交互时,如何将
req.user
设置为我的用户?仅执行 req.user = userSearchResult
(如果在 if
语句内找到用户)或 req.user = user
(如果已创建用户,在 newUser.save()
回调内)是否就足够了,或者我应该调用一些护照函数那会为我设置吗?
与用户注册和登录相关的所有其他护照功能(无需使用 LinkedIn 登录)均运行正常。我只是担心如何让 LinkedIn 登录与护照一起使用。
谢谢你。
passport.js 会自动将
req.user
对象设置为您将作为第二个参数传递给策略回调的 done
函数的对象。
这意味着你应该这样做:
function(req,accessToken, refreshToken, profile, done) {
console.log('authenticated');
console.log(accessToken);
req.session.code = accessToken;
process.nextTick(function () {
// retrieve your user here
getOrCreateUser(profile, function(err, user){
if(err) return done(err);
done(null, user);
})
});
}));
我希望这有帮助。
此代码很有帮助,但我有一个问题,如果有任何问题,请明确以下 api 响应
LinkedIn API 响应:
{
"serviceErrorCode": 100,
"message": "Not enough permissions to access: GET /me",
"status": 403
}