GitHub 接入与 OAuth 2.0 授权全指南
接入 GitHub(第三方登录或调用 API)主要依赖 OAuth 2.0 授权协议。通过接入 GitHub,开发者可以实现“用 GitHub 账号一键登录平台”以及“获取用户公开信息、仓库数据”等功能。
1. 接入前的准备:创建 OAuth App
在开始写代码前,必须先在 GitHub 注册一个 OAuth Application。
登录 GitHub,点击右上角头像 -> Settings(设置)。
在左侧边栏最下方,点击 Developer settings(开发者设置)。
选择 OAuth Apps,点击 New OAuth App(或 Register a new application)。
填写应用信息:
Application name:应用名称(如
MyApp)。Homepage URL:应用主页地址(本地测试可填
http://localhost:3000)。Authorization callback URL:核心字段,授权成功后的回调地址(如
http://localhost:3000/api/v1/auth/callback/github)。
点击 Register application 完成注册。
注册完成后,系统会生成:
Client ID:应用的公开唯一标识。
Client Secret:密钥,点击 Generate a new client secret 生成(切记妥善保管,严禁暴露在前端)。
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_id | String | 是 | 注册应用时获得的 Client ID |
redirect_uri | String | 否 | 授权后的回调地址(必须与配置的回调地址匹配) |
scope | String | 否 | 申请的权限范围,多个权限用空格隔开(如 read:user user:email) |
state | String | 推荐 | 随机生成的不可预测字符串,用于防御 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 中附带 code 与 state:
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)请求头 Header:
Accept: 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_16C7e42F292c6912E7710c838347Ae178B4aUser-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}
简单示例
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 |
5. 安全与开发最佳实践
绝对保护 Client Secret:Client Secret 只能保存在后端服务器的环境变量中,换取 Access Token 的步骤必须在服务端发起。
校验
state参数:前端或服务端发起授权时,生成随机 Token 存入 Session/Cookie,回调时核对是否一致,防止 CSRF 攻击。响应式 User-Agent:发送 HTTP 请求访问 GitHub API 时,必须在 Request Header 中加上自定义
User-Agent,否则请求会被拒绝。Token 安全存储:服务端拿到用户
access_token后,如果要持久化,应进行加密存储(如 AES-256)。
6. 官方关键文档汇总链接
OAuth App 注册指南:Creating an OAuth app
OAuth 授权流程全解析:Authorizing OAuth apps
权限 Scope 详细列表:Scopes for OAuth apps
GitHub REST API 概览:GitHub REST API Documentation
发表评论