OAuth是一种受权机制。OAuth过程中,零碎会询问数据所有者,是否批准受权第三方利用进入零碎获取这些数据,批准,则零碎将产生一个短期的进入令牌(token),用来代替明码,供第三方利用应用。

# OAuth流程(假如你的站点是A网站)1. 用户事件触发(个别点击事件)跳转,到 Github2. Github 要求用户登录,并询问用户是批准 Github 下放受权码给 A 网站3. 用户批准,则 Github 重定向到 A 网站,同时携带一个受权码(code,以url拼接模式下放)4. A 网站应用受权码(code)向 Github 申请令牌(token)5. Github 返回令牌(token)6. A 网站应用令牌,向 Github 申请用户数据7. A 网站获得用户 Github 数据,前端展现登陆,后端存储更新用户数据,并记录登录状态

    本示例中,我的项目前后端拆散开发,前端采纳大家熟知的vue,后端采纳koa2,OAuth逻辑和前后端框架其实无关,只会因为前后端拆散在写法和前后端不拆散我的项目上略有不同。上面别离来说说进行OAuth开发前做的筹备,以及在前后端我的项目中如何编写代码。

一、配置Github

链接:https://github.com/settings/a...

Application name:站点名称,这里假如是a

Homepage URL: 主站链接,本地测试,这里是localhost:8001

Authorization callback URL:Github重定向链接,本地测试,这里是localhost:8001/login

确认后,github将生成OAuth所须要的 clientID 和  clientSecret

二、前端编写

// 将登录办法封装为插件 oauth.jsconst getQuery = require('./getQuery') // 集体编写用来获取url query的办法const oauthGithub = {  getCode() {    const authorize_uri = 'https://github.com/login/oauth/authorize';    const client_id = 'b82f7274e2e996a2cecc';    const redirect_uri = 'http://localhost:8001/login';    location.href = `${authorize_uri}?client_id=${client_id}&redirect_uri=${redirect_uri}`;  },  async getUser(_this) {    const code = getQuery('code');    if (code) {      try {        const res = await _this.$axios.post(`/api/oauth/github?code=${code}`);        if (res.data.errorno) {          _this.$root.$emit('toast', { variant: 'danger', text: '登录失败' }); // 自定义toast        } else {          _this.$store.commit('setUser', res.data.data); // 存储用户数据          _this.$root.$emit('toast', { variant: 'success', text: '登录胜利' });        }      } catch(err) {          _this.$root.$emit('toast', { variant: 'danger', text: '登录失败' });      }    }  }}module.exports = {  oauthGithub}
// 在页面或组件内调用插件办法<template>  <b-card>    <b-row>      <b-col md="4" class="border-right">        <h5 class="pb-2 text-center">第三方登录</h5>        <div class="flex justify-center">          <div class="pointer hover" @click="getCode()">            <b-icon icon="github" font-scale="3"></b-icon>            <p class="m-0 p-0">Github</p>          </div>        </div>      </b-col>    </b-row>  </b-card></template><script>  import { oauthGithub } from '~/plugins/oauth'  export default {    name: 'login',    data() {      return {}    },    mounted() {      oauthGithub.getUser(this); // Github下放code重定向后调用    },    methods: {      getCode() {        oauthGithub.getCode(); // 点击事件触发,获取code      }    }  }</script>

二、后端编写

// 将OAuth独自抽离为一个route:oauth.jsconst router = require('koa-router')()const axios = require('axios')const { SuccessModel, ErrorModel } = require('../model/resModel')const {  handleUser} = require('../controller/oauth')router.prefix('/api/oauth')router.post('/github', async function (ctx, next) {  const clientID = 'b82f7274e2e996a2cecc'  const clientSecret = 'f09aa2=dfhf4ba57b6777307b6200d6d2a'  const code = ctx.query.code  const tokenRes = await axios({    method: 'post',    url: `https://github.com/login/oauth/access_token?client_id=${clientID}&client_secret=${clientSecret}&code=${code}`,    headers: { accept: 'application/json' }  })  const accessToken = tokenRes.data.access_token  if (accessToken) {    const resData = await axios({      method: 'get',      url: `https://api.github.com/user`,      headers: { accept: 'application/json', Authorization: `token ${accessToken}` }    });    const uname = resData.data.login // 用户github账号名    const reqBody = {      nickname: resData.data.name, // 用户github昵称      avatar: resData.data.avatar_url, // 用户github头像      self_introduction: resData.data.bio, // 用户github自我介绍      site: 'github', // 标识用户来自github      site_id: resData.data.id, // 用户github id      create_at: Date.now(), // 用户首次 OAuth 工夫      update_at: Date.now() // 用户最近一次 OAuth 工夫    }    const userData = await handleUser(reqBody, uname) // controller办法,用户首次登录则存储用户,二次及当前登录更新数据    if (userData.id) {      ctx.session.uid = userData.id //redis存储登录状态      ctx.body = new SuccessModel(userData)    } else {      ctx.body = new ErrorModel('登录失败')    }  }})module.exports = router

三、操作演示

  1. A 网站跳转到 Github

  1. 用户确认后,GIthub 重定向到 A 网站,并携带 code

  1. 前端拿到URL query 局部的 code,向 Github 申请数据(token及用户数据获取都在都在后端实现)
// 即route: oauth.js 局部逻辑// 1. 拿到前端传过来的code,向github申请token// 2. 拿到token,向github申请用户数据// 3. 拿到用户数据,将数据返回给前端
  1. 前端拿到用户数据,进行展现

原文链接:https://www.helloque.site/article/22