当前位置: 首页 > news >正文

个人博客开发系列:评论功能之GitHub账号OAuth授权

前言

​ 因为年前换工作(新工作也没之前那么闲了)以及过年的原因,评论功能的开发进度一直很慢,一点一点的也算是完成了一部分功能,这次先写第一篇关于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_idredirect_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的授权流程已经走完,这时我们的数据库中也保存下了用户的一些信息,就可以继续进行之后评论的操作了。

相关文章:

  • Python_函数
  • POJ 2392 Space Elevator(多重背包,排序)
  • ubuntu17.04中启动tnsorboard过程
  • BZOJ3601 一个人的数论
  • 亚马逊推出FreeTime Android应用程序,开放适合儿童资源
  • SpaceX发射机密间谍卫星,系与美国防部签订的第一单合作
  • 无人机给你送餐了,快来签收!
  • 作为“云计算”的延伸,“雾计算”只是一种炒作吗?
  • RT-Thread的线程(任务)处理 rt_thread_create/rt_thread_init区别
  • 命令收集
  • 为实现全局化产品线布局,瑞芯微宣布旗下芯片RK3399 Linux系统开源
  • mongodb--安装和初步使用教程
  • WIFI渗透从入门到精通
  • Webscan360的防御与绕过
  • 装饰器
  • #Java异常处理
  • [数据结构]链表的实现在PHP中
  • 【391天】每日项目总结系列128(2018.03.03)
  • co.js - 让异步代码同步化
  • egg(89)--egg之redis的发布和订阅
  • happypack两次报错的问题
  • Java 23种设计模式 之单例模式 7种实现方式
  • Java面向对象及其三大特征
  • Netty 4.1 源代码学习:线程模型
  • Spark in action on Kubernetes - Playground搭建与架构浅析
  • SpiderData 2019年2月25日 DApp数据排行榜
  • 对象管理器(defineProperty)学习笔记
  • 关于List、List?、ListObject的区别
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 入门到放弃node系列之Hello Word篇
  • 使用 Node.js 的 nodemailer 模块发送邮件(支持 QQ、163 等、支持附件)
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 如何用纯 CSS 创作一个菱形 loader 动画
  • 整理一些计算机基础知识!
  • 直播平台建设千万不要忘记流媒体服务器的存在 ...
  • ​卜东波研究员:高观点下的少儿计算思维
  • #考研#计算机文化知识1(局域网及网络互联)
  • (11)MSP430F5529 定时器B
  • (2009.11版)《网络管理员考试 考前冲刺预测卷及考点解析》复习重点
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (第二周)效能测试
  • (二)JAVA使用POI操作excel
  • (二)构建dubbo分布式平台-平台功能导图
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (十七)Flask之大型项目目录结构示例【二扣蓝图】
  • (一)认识微服务
  • (转)LINQ之路
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .net 发送邮件
  • .net6 webapi log4net完整配置使用流程
  • .NET6实现破解Modbus poll点表配置文件
  • .net快速开发框架源码分享
  • .NET设计模式(8):适配器模式(Adapter Pattern)
  • .NET运行机制