2020-06-29
Ann Ann
所谓第三方登录,实质就是 OAuth 授权。用户想要登录 A 网站,A 网站让用户提供第三方网站的数据,证明自己的身份。获取第三方网站的身份数据,就需要 OAuth 授权。
举例来说,A 网站允许 GitHub 登录,背后就是下面的流程。
- A 网站让用户跳转到 GitHub。
- GitHub 要求用户登录,然后询问“A 网站要求获得 xx 权限,你是否同意?”
- 用户同意,GitHub 就会重定向回 A 网站,同时发回一个授权码。
- A 网站使用授权码,向 GitHub 请求令牌。
- GitHub 返回令牌.
- A 网站使用令牌,向 GitHub 请求用户数据。
下面就是这个流程的代码实现。
一个应用要求 OAuth 授权,必须先到对方网站登记,让对方知道是谁在请求。
所以,你要先去 GitHub 登记一下。当然,我已经登记过了,你使用我的登记信息也可以,但为了完整走一遍流程,还是建议大家自己登记。这是免费的。
访问这个网址,填写登记表。
应用的名称随便填,主页 URL 填写http://localhost:8080
,跳转网址填写 http://localhost:8080/oauth/redirect
。
提交表单以后,GitHub 应该会返回客户端 ID(client ID)和客户端密钥(client secret),这就是应用的身份识别码。
我写了一个代码仓库,请将它克隆到本地。
$ git clone git@github.com:ruanyf/node-oauth-demo.git
$ cd node-oauth-demo
两个配置项要改一下,写入上一步的身份识别码。
index.js
:改掉变量clientID
andclientSecret
public/index.html
:改掉变量client_id
然后,安装依赖。
$ npm install
启动服务。
$ node index.js
浏览器访问http://localhost:8080
,就可以看到这个示例了。
示例的首页很简单,就是一个链接,让用户跳转到 GitHub。
跳转的 URL 如下。
https://github.com/login/oauth/authorize?
client_id=7e015d8ce32370079895&
redirect_uri=http://localhost:8080/oauth/redirect
这个 URL 指向 GitHub 的 OAuth 授权网址,带有两个参数:client_id
告诉 GitHub 谁在请求,redirect_uri
是稍后跳转回来的网址。
用户点击到了 GitHub,GitHub 会要求用户登录,确保是本人在操作。
登录后,GitHub 询问用户,该应用正在请求数据,你是否同意授权。
用户同意授权, GitHub 就会跳转到redirect_uri
指定的跳转网址,并且带上授权码,跳转回来的 URL 就是下面的样子。
http://localhost:8080/oauth/redirect?
code=859310e7cecc9196f4af
后端收到这个请求以后,就拿到了授权码(code
参数)。
这里的关键是针对/oauth/redirect
的请求,编写一个路由,完成 OAuth 认证。
const oauth = async ctx => {
// ...
};
app.use(route.get('/oauth/redirect', oauth));
上面代码中,oauth
函数就是路由的处理函数。下面的代码都写在这个函数里面。
路由函数的第一件事,是从 URL 取出授权码。
const requestToken = ctx.request.query.code;
后端使用这个授权码,向 GitHub 请求令牌。
const tokenResponse = await axios({
method: 'post',
url: 'https://github.com/login/oauth/access_token?' +
`client_id=${clientID}&` +
`client_secret=${clientSecret}&` +
`code=${requestToken}`,
headers: {
accept: 'application/json'
}
});
上面代码中,GitHub 的令牌接口https://github.com/login/oauth/access_token
需要提供三个参数。
client_id
:客户端的 IDclient_secret
:客户端的密钥code
:授权码
作为回应,GitHub 会返回一段 JSON 数据,里面包含了令牌accessToken
。
const accessToken = tokenResponse.data.access_token;
有了令牌以后,就可以向 API 请求数据了。
const result = await axios({
method: 'get',
url: `https://api.github.com/user`,
headers: {
accept: 'application/json',
Authorization: `token ${accessToken}`
}
});
上面代码中,GitHub API 的地址是https://api.github.com/user
,请求的时候必须在 HTTP 头信息里面带上令牌Authorization: token 361507da
。
然后,就可以拿到用户数据,得到用户的身份。
const name = result.data.name;
ctx.response.redirect(`/welcome.html?name=${name}`);
手撕全栈面试题班03期
2025/01/20 08:30 (Sydney)
Python零基础入门
2025/02/12 03:14 (Sydney)
Business Analyst产品经理+实习
2025/02/22 02:38 (Sydney)
地址
Level 10b, 144 Edward Street, Brisbane CBD(Headquarter)Level 2, 171 La Trobe St, Melbourne VIC 3000四川省成都市武侯区桂溪街道天府大道中段500号D5东方希望天祥广场B座45A13号Business Hub, 155 Waymouth St, Adelaide SA 5000Disclaimer
JR Academy acknowledges Traditional Owners of Country throughout Australia and recognises the continuing connection to lands, waters and communities. We pay our respect to Aboriginal and Torres Strait Islander cultures; and to Elders past and present. Aboriginal and Torres Strait Islander peoples should be aware that this website may contain images or names of people who have since passed away.
匠人学院网站上的所有内容,包括课程材料、徽标和匠人学院网站上提供的信息,均受澳大利亚政府知识产权法的保护。严禁未经授权使用、销售、分发、复制或修改。违规行为可能会导致法律诉讼。通过访问我们的网站,您同意尊重我们的知识产权。 JR Academy Pty Ltd 保留所有权利,包括专利、商标和版权。任何侵权行为都将受到法律追究。查看用户协议
© 2017-2024 JR Academy Pty Ltd. All rights reserved.
ABN 26621887572