前言
因为年前换工作 (新工作也没之前那么闲了) 以及过年的原因, 评论功能的开发进度一直很慢, 一点一点的也算是完成了一部分功能, 这次先写第一篇关于 GitHub 账号 OAuth 授权的过程, 之后会再写授权之后如何评论以及评论回复之类的
16 年写第一个博客的时候, 评论时只需要输入昵称以及邮箱即可这次考虑了下, 还是使用 GitHub 的账号来进行访客用户的管理比较好, 顺便练下这类授权登录(QQ 微信等第三方账号授权登录类似)
源码
前端页面: Talk is cheap.
后端接口: Show me the code.
GitHub 授权过程
1. 在自己的 GitHub 中注册 OAuth Apps
2. 点击触发登录, 跳转到授权页面
- // components/Comment.vue 页面
- githubLogin: function () {
- window.location.href = 'https://github.com/login/oauth/authorize?client_id=6625cb27769b1bc52415&redirect_uri=http://localhost:3000/login&scope=user:email';
- window.localStorage.setItem('GITHUB_LOGIN_REDIRECT_URL', `${this.$route.path}?comment=new`);
- }
其中:
https://github.com/login/oauth/authorize
是需要跳转的授权地址, client_id 和 redirect_uri 都是在 GitHub 设置中的内容, 保持一致即可 scope 是获取用户信息的范围, 更多的值可以参考官方文档
localStorage 中存储当前页面的地址, 是为了后续授权登录成功之后跳转到当前的页面, comment=new 参数是为了与正常访问的当前页面作区分
4. 跳到官方提供的授权页面
5. 确认授权后会跳转到
http://localhost:3000/login?code=aa043845e6b80253919f
页面
跳转到 login 页面是为了显示等待页面, 同事为了存储后续接口的返回值, 并进行相应的跳转最开始是之前跳转到一个接口的, 但处理起来会更麻烦一些
- // pages/login.vue 页面
- mounted () {
- return axios.get(`/oauth/github/github_oauth?code=${this.$route.query.code}`).then(res => {
- if (res.data.success === 1) {
- let guest = {
- userName: res.data.userName,
- avatar: res.data.avatar
- };
- window.localStorage.setItem('GITHUB_LOGIN_TOKEN', res.data.token);
- window.localStorage.setItem('GITHUB_LOGIN_GUEST', JSON.stringify(guest));
- let redirectUrl = window.localStorage.getItem('GITHUB_LOGIN_REDIRECT_URL');
- this.$router.push({ path: redirectUrl });
- }
- });
- }
6. 后端接口根据返回的 code 值处理授权
此处需要在后端中发起两个请求:
1. 第一个请求用来获取到用户授权后的 access_token
2. 第二个请求会根据第一个请求获取到的 access_token 来取得用户信息
- // server/api/oauth/github.controller.js
- exports.githubOAuth = async(ctx) => {
- const code = ctx.query.code;
- let path = 'https://github.com/login/oauth/access_token';
- const params = {
- client_id: config.oAuth.github.client_id,
- client_secret: config.oAuth.github.client_secret,
- code: code
- };
- await fetch(path, {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: JSON.stringify(params)
- })
- .then(res => {
- return res.text();
- })
- .then(body => {
- const args = body.split('&');
- let arg = args[0].split('=');
- return arg[1];
- })
- .then(async(token) => {
- const url = 'https://api.github.com/user?access_token=' + token;
- await fetch(url)
- .then(res => {
- return res.json();
- })
- .then(async(res) => {
- let userId = 0;
- /**
- * 用户保存过程, 有需要可查看源码
- */
- if (userId > 0) {
- ctx.session.user = res.login;
- // 用户 token
- const userToken = {
- name: res.login,
- id: userId
- };
- // 签发 token
- const token = jwt.sign(userToken, config.tokenSecret, { expiresIn: '2h' });
- ctx.body = {
- success: 1,
- token: token,
- userName: res.login,
- avatar: res.avatar_url,
- message: ''
- };
- } else {
- ctx.body = {
- success: 0,
- token: '',
- message: 'GitHub 授权登录失败'
- };
- }
- });
- })
- .catch(e => {
- console.log(e);
- ctx.body = {
- success: 0,
- token: '',
- message: 'GitHub 授权登录失败'
- };
- });
- };
总结
经过以上几个步骤, GitHub 的授权流程已经走完, 这时我们的数据库中也保存下了用户的一些信息, 就可以继续进行之后评论的操作了
来源: https://juejin.im/post/5a9a68e7f265da23994dfb1f