按 Enter 键跳转到正文

GitHub 接入与 OAuth 2.0 授权全指南

接入 GitHub(第三方登录或调用 API)主要依赖 OAuth 2.0 授权协议。通过接入 GitHub,开发者可以实现“用 GitHub 账号一键登录平台”以及“获取用户公开信息、仓库数据”等功能。

1. 接入前的准备:创建 OAuth App

在开始写代码前,必须先在 GitHub 注册一个 OAuth Application。

  1. 登录 GitHub,点击右上角头像 -> Settings(设置)。

  2. 在左侧边栏最下方,点击 Developer settings(开发者设置)。

  3. 选择 OAuth Apps,点击 New OAuth App(或 Register a new application)。

  4. 填写应用信息:

    • Application name:应用名称(如 MyApp)。

    • Homepage URL:应用主页地址(本地测试可填 http://localhost:3000)。

    • Authorization callback URL核心字段,授权成功后的回调地址(如 http://localhost:3000/api/v1/auth/callback/github)。

  5. 点击 Register application 完成注册。

  6. 注册完成后,系统会生成:

    • Client ID:应用的公开唯一标识。

    • Client Secret:密钥,点击 Generate a new client secret 生成(切记妥善保管,严禁暴露在前端)。

官方参考文档Creating an OAuth app - GitHub Docs

2. GitHub OAuth 2.0 核心交互流程

GitHub OAuth 2.0 采用标准的授权码模式(Authorization Code Grant)

 1
 2+----------+                               +-------------------------------+
 3|          |--(A)- 重定向至 GitHub 授权页 ->|                               |
 4|          |                               |  GitHub 授权服务器 (GitHub)    |
 5|          |<--(B)- 带授权 Code 回调应用 ---|                               |
 6|          |                               +-------------------------------+
 7|  客户端   |                               
 8| (应用)   |                               +-------------------------------+
 9|          |--(C)- 用 Code+Secret 换 Token->|                               |
10|          |<--(D)- 返回 Access Token -----|  GitHub 令牌/API 服务器        |
11|          |                               |                               |
12|          |--(E)- 携带 Token 请求 API ---->|                               |
13|          |<--(F)- 返回 用户数据/资源 -----|                               |
14+----------+                               +-------------------------------+

3. 详细对接步骤与 API 接口规范

步骤一:引导用户前往 GitHub 授权页

前端点击“使用 GitHub 登录”按钮时,将用户浏览器重定向至 GitHub 授权地址:

  • 请求方式GET

  • 请求 URL[https://github.com/login/oauth/authorize](https://github.com/login/oauth/authorize)

  • 参数说明

参数名类型是否必填说明
client_idString注册应用时获得的 Client ID
redirect_uriString授权后的回调地址(必须与配置的回调地址匹配)
scopeString申请的权限范围,多个权限用空格隔开(如 read:user user:email
stateString推荐随机生成的不可预测字符串,用于防御 CSRF 跨站请求伪造

拼接示例

1
2https://github.com/login/oauth/authorize?client_id=YOUR_CLIENT_ID&scope=read:user%20user:email&state=RANDOM_STATE_STRING

步骤二:接收临时 Code 并换取 Access Token

用户在 GitHub 页面点击“同意授权”后,GitHub 会重定向回你的 redirect_uri,并在 URL 中附带 codestate

1
2http://localhost:3000/api/v1/auth/callback/github?code=AUTH_CODE_HERE&state=RANDOM_STATE_STRING

后端接收到 code 后,向 GitHub 发起服务端 POST 请求换取 Access Token:

  • 请求方式POST

  • 请求 URL[https://github.com/login/oauth/access_token](https://github.com/login/oauth/access_token)

  • 请求头 HeaderAccept: application/json(默认 GitHub 会返回 query 字符串,设置 Header 可直接获取 JSON 格式响应)

  • 请求 Body 参数

1{
2  "client_id": "YOUR_CLIENT_ID",
3  "client_secret": "YOUR_CLIENT_SECRET",
4  "code": "AUTH_CODE_HERE"
5}
  • 响应示例
1{
2  "access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
3  "token_type": "bearer",
4  "scope": "read:user,user:email"
5}

步骤三:使用 Access Token 获取用户信息

拿到 access_token 后,就可以调用 GitHub REST API 获取用户的公开资料:

  • 请求方式GET

  • 请求 URL[https://api.github.com/user](https://api.github.com/user)

  • 请求头 Header

    • Authorization: Bearer gho_16C7e42F292c6912E7710c838347Ae178B4a

    • User-Agent: Your-App-Name必须配置,GitHub API 强制要求设置 User-Agent,否则返回 403)

  • 响应示例

1{
2  "login": "octocat",
3  "id": 583231,
4  "avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4",
5  "name": "The Octocat",
6  "email": "octocat@github.com"
7}

官方参考文档Authorizing OAuth apps - GitHub Docs

简单示例

 1<!DOCTYPE html>
 2<html lang="zh-CN">
 3<head>
 4    <meta charset="UTF-8">
 5    <title>GitHub OAuth 示例</title>
 6</head>
 7<body>
 8    <h2>GitHub 登录示例</h2>
 9    <button id="login-btn">使用 GitHub 登录</button>
10    <div id="user-info"></div>
11
12    <script>
13        // 1. 配置你的 GitHub Client ID 和后端回调接口
14        const CLIENT_ID = '你的_GITHUB_CLIENT_ID';
15        const REDIRECT_URI = 'http://localhost:3000/callback.html'; // 授权后的回调页面
16
17        const loginBtn = document.getElementById('login-btn');
18
19        // 点击按钮,跳转到 GitHub 授权页
20        loginBtn.addEventListener('click', () => {
21            const authUrl = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&scope=read:user%20user:email`;
22            window.location.href = authUrl;
23        });
24
25        // 2. 判断当前页面是否处于授权回调状态(URL 中是否有 code)
26        const urlParams = new URLSearchParams(window.location.search);
27        const code = urlParams.get('code');
28
29        if (code) {
30            document.getElementById('user-info').innerText = '正在登录,换取 Token 中...';
31            
32            // 将 code 发送到你自己的 Node.js 后端换取 Token
33            fetch('http://localhost:3000/api/github/token', {
34                method: 'POST',
35                headers: { 'Content-Type': 'application/json' },
36                body: JSON.stringify({ code })
37            })
38            .then(res => res.json())
39            .then(data => {
40                if (data.access_token) {
41                    document.getElementById('user-info').innerHTML = `
42                        <h3>登录成功!</h3>
43                        <p><b>Access Token:</b> ${data.access_token}</p>
44                        <p><b>用户名:</b> ${data.user.login}</p>
45                        <img src="${data.user.avatar_url}" width="100" />
46                    `;
47                } else {
48                    document.getElementById('user-info').innerText = '登录失败:' + (data.error || '未获取到 Token');
49                }
50            })
51            .catch(err => {
52                console.error(err);
53                document.getElementById('user-info').innerText = '请求后端服务出错';
54            });
55        }
56    </script>
57</body>
58</html>

4. 常见权限范围(Scopes)

在步骤一请求授权时,可以通过 scope 参数控制请求的权限大小,遵循最小权限原则

Scope 标识权限说明
(空)仅获取公开信息(公开仓库、公开 Profile 数据)
read:user读取用户的基本 Profile 数据
user:email读取用户的私有邮箱地址
repo获取用户私有仓库及公开仓库的完整读写权限
gist创建与管理用户的 Gist

官方参考文档Scopes for OAuth apps - GitHub Docs

5. 安全与开发最佳实践

  1. 绝对保护 Client Secret:Client Secret 只能保存在后端服务器的环境变量中,换取 Access Token 的步骤必须在服务端发起。

  2. 校验 state 参数:前端或服务端发起授权时,生成随机 Token 存入 Session/Cookie,回调时核对是否一致,防止 CSRF 攻击。

  3. 响应式 User-Agent:发送 HTTP 请求访问 GitHub API 时,必须在 Request Header 中加上自定义 User-Agent,否则请求会被拒绝。

  4. Token 安全存储:服务端拿到用户 access_token 后,如果要持久化,应进行加密存储(如 AES-256)。

6. 官方关键文档汇总链接

发表评论