1. 所谓第三方登录,实质就是 OAuth 授权;
  2. 用户想要登录 github 网站,github 网站让用户提供第三方网站的数据,证明自己的身份;
  3. 获取第三方网站的身份数据,就需要 OAuth 授权;

实现原理

  1. A 网站让用户跳转到 GitHub (发起一个认证的请求);

  2. 将这个认证请求重定向到 github 网站;

  3. GitHub 要求用户登录,然后询问 "A 网站要求获得 xx 权限,你是否同意?"

  4. 用户同意后 GitHub 就会重定向回 A 网站,同时发回一个授权码;

  5. A 网站使用授权码,向 GitHub 请求令牌;

  6. GitHub 返回令牌;

  7. A 网站使用令牌,向 GitHub 请求用户数据;

实现流程

本地创建应用服务

应用登记

  1. GitHub 服务器配置

  2. setting => developer settings => OAuth Apps => 应用信息填写 => generate a new client secret

  3. 登记完成之后,获取到生成的 Client IDClient Secret,这就是应用的身份识别码;

github 跳转地址相关

url 请求方法 请求参数 说明
https://github.com/login/oauth/authorize GET client_id: string 应用唯一标识 授权码 code 获取地址
https://github.com/login/oauth/access_token POST client_id: string 用户唯一标识
client_secret 用户申请密钥
code 授权码
令牌 获取地址
https://api.github.com/user GET 请求头添加 { headers: Authorization } 令牌 用户信息获取地址

代码实现

  1. 前端进行登录地址创建

  2. 后端进行授权码地址重定向

  3. 路由匹配 github 返回地址

  4. 获取授权码 code 进行令牌请求

  5. 获取令牌请求数据,进行界面渲染

  1. index.js

    const Koa = require("koa");
    const router = require("koa-router")();
    const staticFiles = require('koa-static');
    const path = require('path');
    const views = require('koa-views');
    const axios = require('axios');
    const qs = require('qs');
    const app = new Koa();
    
    let userInfo = {};
    
    app.use(staticFiles(path.resolve(__dirname, "./public")));
    app.use(views('views', { map: { html: 'ejs' } }));
    
    /* 模板路由处理 */
    router.get('/login', async ctx => {
      await ctx.render('login');
    })
    router.get('/home', async ctx => {
      await ctx.render('home', { userInfo });
    })
    
    /* 拦截前端的 a 链接跳转 */
    router.get('/loginByGithub', async ctx => {
      /* 跳转到 git 获取授权码的地址  携带了 client_id 参数*/
      const path = 'https://github.com/login/oauth/authorize?client_id=3d7f48adf0ebf54b92c8'
      ctx.redirect(path);
    })
    
    /* 创建一个授权码的地址路由 */
    router.get('/callback/github', async ctx => {
      const { code } = ctx.query;
    
      /* 请求令牌 post  params 参数 */
      const accessToken = await axios.post('https://github.com/login/oauth/access_token', {
        client_id: '3d7f48adf0ebf54b92c8',
        client_secret: '870a993278809793e5aae442331e613e8508f2d1',
        code
      });
      
      const { access_token } = qs.parse(accessToken.data);
      /* 获取用户的信息 */
      userInfo = await axios.get('https://api.github.com/user', {
        /* Bearer 后面记得跟一个空格 */
        headers: {
          Authorization: `Bearer ${access_token}`, 
        }
      })
      userInfo = userInfo.data;
      ctx.redirect('/home');
    })
    
    app.use(router.routes());
    app.listen(8888, () => console.log('server is running on port 8888'));
    
  2. login.html

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>登录界面</title>
        <link rel="stylesheet" href="/css/user.css">
    </head>
    
    <body>
        <div class="form-container">
            <h1 class="title">用户登录</h1>
            <form id="formContainer" class="form-wrapper">
                <div class="form-item">
                    <input id="userName" class="text" type="text" placeholder="请输入登录账号">
                </div>
                <div class="form-item password-container">
                    <input id="userPassword" type="password" placeholder="请输入登录密码">
                </div>
                <input type="submit" class="signin" value="登录">
            </form>
            <a href="/loginByGithub" class="other-login-methods">使用github账户进行登录</a>
            <div class="copy-rights">
                <p>Copyright © 2015.Company name All rights reserved.<a class="switch-register" href="/register.html">还没有有账号,立即注册</a></p>
            </div>
        </div>
    </body>
    
    </html>
    
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 实现原理
  2. 2. 实现流程
    1. 2.1. 应用登记
    2. 2.2. github 跳转地址相关
    3. 2.3. 代码实现