81 lines
2.8 KiB
Markdown
81 lines
2.8 KiB
Markdown
---
|
|
id: 589a8eb3f9fc0f352b528e72
|
|
title: 实现第三种社交登录
|
|
challengeType: 2
|
|
forumTopicId: 301558
|
|
dashedName: implementation-of-social-authentication-iii
|
|
---
|
|
|
|
# --description--
|
|
|
|
验证策略的最后一部分是处理从 GitHub 返回的个人信息。 如果用户存在,我们就需要从数据库中读取用户数据并在 profile 页面加载;否则,我们需要把用户信息添加到数据库。 GitHub 在用户信息中为我们提供了独一无二的 *id*,我们可以通过序列化的 id 在数据库中搜索用户(已实现)。 以下是这个逻辑的实现示例,我们应该把它传到新策略的第二个参数,就是目前 `console.log(profile);` 的下方:
|
|
|
|
```js
|
|
myDataBase.findOneAndUpdate(
|
|
{ id: profile.id },
|
|
{
|
|
$setOnInsert: {
|
|
id: profile.id,
|
|
name: profile.displayName || 'John Doe',
|
|
photo: profile.photos[0].value || '',
|
|
email: Array.isArray(profile.emails)
|
|
? profile.emails[0].value
|
|
: 'No public email',
|
|
created_on: new Date(),
|
|
provider: profile.provider || ''
|
|
},
|
|
$set: {
|
|
last_login: new Date()
|
|
},
|
|
$inc: {
|
|
login_count: 1
|
|
}
|
|
},
|
|
{ upsert: true, new: true },
|
|
(err, doc) => {
|
|
return cb(null, doc.value);
|
|
}
|
|
);
|
|
```
|
|
|
|
`findOneAndUpdate` 的作用是在数据库中查询对象并更新, 如果对象不存在,将插入对象,然后我们可以在回调方法里获取到插入的新对象。 在这个例子中,我们会设置 `last_login`,而且总会为 `login_count` 加 `1`。只有在插入一个新对象(新用户)时,我们才会初始化这些字段。 另外,还需要注意默认值的使用。 有时返回的用户信息可能不全,可能是因为用户没有填写,也可能是因为用户选择不公开一部分信息。 在这种情况下,我们需要进行相应的处理,以防我们的 app 报错。
|
|
|
|
你现在应该可以登录你的应用了,试试吧。
|
|
|
|
完成上述要求后,你可以在下方提交你的页面链接。 如果你遇到了问题,可以参考 [这里](https://gist.github.com/camperbot/183e968f0e01d81dde015d45ba9d2745) 的答案。
|
|
|
|
# --hints--
|
|
|
|
GitHub 策略应配置完成。
|
|
|
|
```js
|
|
(getUserInput) =>
|
|
$.get(getUserInput('url') + '/_api/auth.js').then(
|
|
(data) => {
|
|
assert.match(
|
|
data,
|
|
/GitHubStrategy[^]*myDataBase/gi,
|
|
'Strategy should use now use the database to search for the user'
|
|
);
|
|
assert.match(
|
|
data,
|
|
/GitHubStrategy[^]*return cb/gi,
|
|
'Strategy should return the callback function "cb"'
|
|
);
|
|
},
|
|
(xhr) => {
|
|
throw new Error(xhr.statusText);
|
|
}
|
|
);
|
|
```
|
|
|
|
# --solutions--
|
|
|
|
```js
|
|
/**
|
|
Backend challenges don't need solutions,
|
|
because they would need to be tested against a full working project.
|
|
Please check our contributing guidelines to learn more.
|
|
*/
|
|
```
|