hi - blog

如何从零开始接入 GitHub OAuth

如何从零开始接入 GitHub OAuth

前言

本文将介绍如何访问基于OAuth2协议的GitHub用户信息API接口以及如何自己实现一个简单的基于授权码模式的认证服务器,如果对OAuth2的基本概念和四种授权模式还不熟悉,可以先看一下阮一峰老师的博客:OAuth 2.0 的一个简单解释,本文则主要以实际的项目来讲解使用方法。

GitHub OAuth

前置准备

首先需要创建一个应用 创建应用

打开此链接会出现一下页面,内容自己看着填就好

创建应用

这里需要将Client ID以及点击Generate a new client secret后生成的Client Secret进行保存用于后续使用。

生成密钥

开始构建node服务器

个人认为这个授权跟微信公众号的登录有点相像

首先创建一个node应用

mkdir github_oauth_node
cd github_oauth_node && npm init --yes

我这里用的是 express 框架,大家自行选择,都是大同小异

## 安装依赖
npm i express dotenv nodemon axios

创建一个 app.js.env 文件作为此项目的服务器

touch app.js .env static/index.html

配置 .env

PORT=8989
GITHUB_CLIENT_ID=YOUR_CLIENT_ID
GITHUB_CLIENT_SECRET=YOUR_CLIENT_SECRET

配置 app.js

const express = require('express')
require('dotenv').config()

// 将变量结构出来
const { GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, PORT } = process.env

const app = express()

// 静态页面
app.use('*', express.static(__dirname + '/static'))

const PORT = PORT || 5555
app.listen(PORT, () => {
    console.log(`服务已启动 http://127.0.0.1:${PORT}`)
})

前端测试页面

<!-- static/index.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>GITHUB 登录</title>
    </head>
    <body>
        <a href="/oauth">GitHub 登录</a>
    </body>
</html>

修改 package.jsonscripts 脚步

...
"scripts": {
    "start": "nodemon app.js"
},
...

启动服务 npm run start

访问 http://localhost:8989

静态页面

出现该页面表示服务启动成功

业务搭建

1. 请求用户的 GitHub 标识

/// app.js
...

const redirect_url = 'http://localhost:8989/oauth_callback'

// 点击 index.html 下的 超链接走的路径
app.get('/oauth', async(req, res) => {
    const github_auth = 'https://github.com/login/oauth/authorize/'
    const state = Math.random()
		.toString(36)
		.slice(-6)
    const url = `${github_auth}?client_id=${GITHUB_CLIENT_ID}&redirect_uri=${redirect_url}&scope=user&state=${state}`
    // 重定向至该 url 获取 code
    res.redirect(url)
})

...

2. 通过 code 获取 access_token 并且获取到该用户的信息

...
const axios = require('axios')

app.get('/oauth_callback', async(req, res) => {
    const code = req.query.code
    const data = {
        client_id: GITHUB_CLIENT_ID,
        client_secret: GITHUB_CLIENT_SECRET,
        code,
    }
    const config = { 
        headers: { accept: 'application/json' } 
    }
    
    // data 格式 
    /**
        Accept: application/json
        {
          "access_token":"gho_16C7e42F292c6912E7710c838347Ae178B4a",
          "scope":"repo,gist",
          "token_type":"bearer"
        }
        
        Accept: application/xml
        <OAuth>
          <token_type>bearer</token_type>
          <scope>repo,gist</scope>
          <access_token>gho_16C7e42F292c6912E7710c838347Ae178B4a</access_token>
        </OAuth>
    */
    const { data } = 
                    await axios
                    .post('https://github.com/login/oauth/access_token',
                    data,
                    config)
    
    // 如果获取到当前 data 
    let access_token = ''
    if(data) {
        const token_type = data.data.token_type.charAt(0).toUpperCase()
  + word.slice(1) // 将获取到的 token_type 首字母大写
        access_token = `${token_type} ${data.access_token}`
        const config = {
            headers: {
                Authorization: access_token,
                Accept: 'application/vnd.github+json',
            }
        }
        const user_response = 
                await axios
                .get('https://api.github.com/user', config})
        console.log(user.data, ' =========> user')
    }
})

...

下方图片为打印到的当前用户信息,可以返回给前端页面,也可以保存到数据库,看你们需求

用户信息

以上为 github 的 OAuth 第三方登录,其他的第三方也都大同小异。

为了方便,所以没做什么逻辑处理只是简单的实现了一下功能。本文源代码

参考文献

Current profile photo
© 2022 hi - blog
京ICP备2022015573号-1