接入 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):
+----------+ +-------------------------------+
| |--(A)- 重定向至 GitHub 授权页 ->| |
| | | GitHub 授权服务器 (GitHub) |
| |<--(B)- 带授权 Code 回调应用 ---| |
| | +-------------------------------+
| 客户端 |
| (应用) | +-------------------------------+
| |--(C)- 用 Code+Secret 换 Token->| |
| |<--(D)- 返回 Access Token -----| GitHub 令牌/API 服务器 |
| | | |
| |--(E)- 携带 Token 请求 API ---->| |
| |<--(F)- 返回 用户数据/资源 -----| |
+----------+ +-------------------------------+
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 跨站请求伪造 |
拼接示例:
https://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:
http://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 参数:
{
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code": "AUTH_CODE_HERE"
}
- 响应示例:
{
"access_token": "gho_16C7e42F292c6912E7710c838347Ae178B4a",
"token_type": "bearer",
"scope": "read:user,user:email"
}
步骤三:使用 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)
响应示例:
{
"login": "octocat",
"id": 583231,
"avatar_url": "https://avatars.githubusercontent.com/u/583231?v=4",
"name": "The Octocat",
"email": "octocat@github.com"
}
简单示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>GitHub OAuth 示例</title>
</head>
<body>
<h2>GitHub 登录示例</h2>
<button id="login-btn">使用 GitHub 登录</button>
<div id="user-info"></div>
<script>
// 1. 配置你的 GitHub Client ID 和后端回调接口
const CLIENT_ID = '你的_GITHUB_CLIENT_ID';
const REDIRECT_URI = 'http://localhost:3000/callback.html'; // 授权后的回调页面
const loginBtn = document.getElementById('login-btn');
// 点击按钮,跳转到 GitHub 授权页
loginBtn.addEventListener('click', () => {
const authUrl = `https://github.com/login/oauth/authorize?client_id=${CLIENT_ID}&redirect_uri=${encodeURIComponent(REDIRECT_URI)}&scope=read:user%20user:email`;
window.location.href = authUrl;
});
// 2. 判断当前页面是否处于授权回调状态(URL 中是否有 code)
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
if (code) {
document.getElementById('user-info').innerText = '正在登录,换取 Token 中...';
// 将 code 发送到你自己的 Node.js 后端换取 Token
fetch('http://localhost:3000/api/github/token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ code })
})
.then(res => res.json())
.then(data => {
if (data.access_token) {
document.getElementById('user-info').innerHTML = `
<h3>登录成功!</h3>
<p><b>Access Token:</b> ${data.access_token}</p>
<p><b>用户名:</b> ${data.user.login}</p>
<img src="${data.user.avatar_url}" width="100" />
`;
} else {
document.getElementById('user-info').innerText = '登录失败:' + (data.error || '未获取到 Token');
}
})
.catch(err => {
console.error(err);
document.getElementById('user-info').innerText = '请求后端服务出错';
});
}
</script>
</body>
</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