freeCodeCamp/curriculum/challenges/chinese/06-quality-assurance/advanced-node-and-express/implementation-of-social-au...

75 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

---
id: 589a69f5f9fc0f352b528e70
title: 实现社交账号登陆 (1)
challengeType: 2
forumTopicId: 301559
---
# --description--
第三方用户验证的实现逻辑如下:
1. 在用户点击按钮或者链接后,进入验证页面,通过第三方平台(如 GitHub来进行用户验证。
2. 需要在路由中调用`passport.authenticate('github')`,跳转至 GitHub 验证页面。
3. 页面跳转到 GitHub 上,如果用户未登录 GitHub就需要在这里进行登录。登录成功后会出现向用户申请访问权限的确认页。
4. 如果用户同意访问,则用户会回到我们提供的回调地址,带着 GitHub 那边提供的用户信息回到我们的 app 中。
5. 验证已完成。在我们的应用中,我们需要查询这个用户是否已经存在。如果是新用户,那我们需要把他的用户信息存储到数据库。
在 OAuth 验证策略中,我们至少需要提供 *Client ID**Client Secret*,这样第三方平台就会获悉验证请求的来源,以及这个来源是否有效。为此,需要去我们使用的第三方验证平台(比如 GitHub获取这两个字段的值。注意我们获取到的这个值是唯一的且仅对我们的当前 app 有效——**因此,千万不要分享给别人**,更不要上传到公共仓库或者直接写在代码里。通常,我们会在 *.env* 文件里配置,并在 Node.js 里通过:`process.env.GITHUB_CLIENT_ID`获取。对于这次挑战,我们将会使用 GitHub 作为验证平台。
首先,你需要进入账户设置里的 [Developer settings](https://github.com/settings/developers)板块,然后在 OAuth Apps 获取 *Client ID**Client Secret*。点击 'Register a new application',设置你的应用名称,然后把你的 glitch 主页地址(**注意,不是项目代码的地址**)粘贴到 Homepage URL。然后回调 url 需要设置成上面 Homepage URL 里你粘贴的地址,但后面要加上 '/auth/github/callback'。这样在用户通过 Github 验证后才能跳转到我们指定的页面。别忘了,我们还需要在 .env 文件里配置好 'GITHUB_CLIENT_ID' 和 'GITHUB_CLIENT_SECRET'。
然后,请在你现在的项目里,为 /auth/github 和 /auth/github/callback 创建两个接收 GET 请求的路由。第一个只需要通过 passport 来调用 'github' 验证,第二个需要调用 passport 来验证 'github',但需要在失败时跳转回主页 '/',成功是跳转到用户页面 '/profile'。跳转的逻辑与上一个项目中的逻辑一样。
例如 '/auth/github/callback' 应该像我们处理在上一个项目中一般的登录一样:
```js
app.route('/login')
.post(passport.authenticate('local', { failureRedirect: '/' }), (req,res) => {
res.redirect('/profile');
});
```
完成上述要求后,你可以在下方提交你的页面链接。如果你遇到了问题,可以参考 [这里](https://gist.github.com/camperbot/1f7f6f76adb178680246989612bea21e) 的答案。
# --hints--
路由 /auth/github 应正确配置。
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/routes.js').then(
(data) => {
assert.match(
data,
/('|")\/auth\/github('|")[^]*get.*passport.authenticate.*github/gi,
'Route auth/github should only call passport.authenticate with github'
);
},
(xhr) => {
throw new Error(xhr.statusText);
}
);
```
路由 /auth/github/callback 应正确配置。
```js
(getUserInput) =>
$.get(getUserInput('url') + '/_api/routes.js').then(
(data) => {
assert.match(
data,
/('|")\/auth\/github\/callback('|")[^]*get.*passport.authenticate.*github.*failureRedirect:( |)("|')\/\2/gi,
'Route auth/github/callback should accept a get request and call passport.authenticate for github with a failure redirect to home'
);
},
(xhr) => {
throw new Error(xhr.statusText);
}
);
```
# --solutions--