0%

如何集成Github登录

现在越来越多的网站不再自建登录系统,而是采用第三方登录的方式。比如:QQ、微信、微博、Github等。

其中Github登录是偏技术类网站或新一些的网站的首选,因为它的开放API和生态系统非常强大。

那么如何集成Github登录呢?本文介绍前端主导的Github登录流程。

OAuth2.0 基本概念

Github登录使用的是OAuth2.0协议。OAuth2.0是一个授权框架,允许第三方应用获取对用户资源的有限访问权限。

在OAuth2.0中,主要涉及四个角色:

  1. 资源所有者(用户)
  2. 客户端(第三方应用)
  3. 授权服务器(Github的OAuth服务)
  4. 资源服务器(Github的API服务)

创建Github OAuth应用

  1. 登录Github,进入Settings -> Developer settings -> OAuth Apps
  2. 点击”New OAuth App”按钮
  3. 填写应用信息:
    • Application name:应用名称
    • Homepage URL:应用主页URL
    • Application description:应用描述(可选)
    • Authorization callback URL:授权回调URL
  4. 创建完成后,你会获得Client ID和Client Secret

注意:Client Secret 是非常重要的,一定不能放在前端,千万不要泄露给任何人!

前端实现

1. 发起授权请求

1
2
3
4
5
6
7
8
9
10
11
const clientId = 'your_client_id';
const redirectUri = 'your_redirect_uri';
const scope = 'read:user user:email'; // 根据需要设置权限范围

function redirectToGithub() {
const authUrl = `https://github.com/login/oauth/authorize?client_id=${clientId}&redirect_uri=${redirectUri}&scope=${scope}`;
window.location.href = authUrl;
}

// 在登录按钮点击时调用
document.getElementById('github-login').addEventListener('click', redirectToGithub);

2. 处理回调

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// callback.js
async function handleCallback() {
const code = new URLSearchParams(window.location.search).get('code');
if (!code) return;

try {
// 向后端发送code获取access token
const response = await fetch('/api/github/callback', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ code })
});

const data = await response.json();
if (data.access_token) {
// 保存token并获取用户信息
localStorage.setItem('github_token', data.access_token);
await fetchUserInfo(data.access_token);
}
} catch (error) {
console.error('Github登录失败:', error);
}
}

async function fetchUserInfo(token) {
try {
const response = await fetch('https://api.github.com/user', {
headers: {
'Authorization': `token ${token}`
}
});
const userInfo = await response.json();
console.log('用户信息:', userInfo);
// 处理登录成功后的逻辑
} catch (error) {
console.error('获取用户信息失败:', error);
}
}

// 页面加载时检查是否有授权码
document.addEventListener('DOMContentLoaded', handleCallback);

服务端实现

服务端主要负责处理Github OAuth的核心流程,主要是code换取token必须在服务端进行。用express框架做一个简易示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 使用express框架
const express = require('express');
const axios = require('axios');
const app = express();

// 环境变量中配置
const clientId = process.env.GITHUB_CLIENT_ID;
const clientSecret = process.env.GITHUB_CLIENT_SECRET;

app.post('/api/github/callback', async (req, res) => {
const { code } = req.body;

try {
// 使用code换取access token
const tokenResponse = await axios.post('https://github.com/login/oauth/access_token', {
client_id: clientId,
client_secret: clientSecret,
code: code
}, {
headers: {
Accept: 'application/json'
}
});

const { access_token } = tokenResponse.data;

// 返回必要信息给前端
res.json({
access_token,
});

} catch (error) {
console.error('Github OAuth Error:', error);
res.status(500).json({
error: '授权失败'
});
}
});

// 启动服务器
app.listen(3000, () => {
console.log('Server is running on port 3000');
});

服务端注意事项

  1. 安全存储

    • Client Secret必须安全存储,推荐使用环境变量
    • 用户token要加密存储在数据库中
  2. Token管理

    • 实现token过期和刷新机制
    • 定期清理无效token
  3. 错误处理

    • 完善的错误日志记录
    • 友好的错误提示
  4. 并发控制

    • 防止重复授权请求
    • 使用Redis等缓存提高性能

最佳实践

  1. 错误处理:实现完善的错误处理机制,为用户提供清晰的错误提示。

  2. Loading状态:在授权过程中显示loading状态,提升用户体验。

  3. Token管理:合理管理access token的存储和刷新机制。

  4. 用户体验:提供清晰的登录按钮和流程提示。

总结

Github OAuth登录的实现并不复杂,关键是要理解OAuth2.0的基本流程,注意安全性问题,并做好错误处理和用户体验优化。通过以上步骤,你就可以为你的应用添加Github登录功能了。

本文主要介绍的是重前端的方式来实现这个,但真实项目中这些事项更应该放在服务端进行,后续有机会再分享重服务端的实现。