如何集成Github登录
现在越来越多的网站不再自建登录系统,而是采用第三方登录的方式。比如:QQ、微信、微博、Github等。
其中Github登录是偏技术类网站或新一些的网站的首选,因为它的开放API和生态系统非常强大。
那么如何集成Github登录呢?本文介绍前端主导的Github登录流程。
OAuth2.0 基本概念
Github登录使用的是OAuth2.0协议。OAuth2.0是一个授权框架,允许第三方应用获取对用户资源的有限访问权限。
在OAuth2.0中,主要涉及四个角色:
- 资源所有者(用户)
- 客户端(第三方应用)
- 授权服务器(Github的OAuth服务)
- 资源服务器(Github的API服务)
创建Github OAuth应用
- 登录Github,进入Settings -> Developer settings -> OAuth Apps
- 点击"New OAuth App"按钮
- 填写应用信息:
- Application name:应用名称
- Homepage URL:应用主页URL
- Application description:应用描述(可选)
- Authorization callback URL:授权回调URL
- 创建完成后,你会获得Client ID和Client Secret
注意:Client Secret 是非常重要的,一定不能放在前端,千万不要泄露给任何人!
前端实现
1. 发起授权请求
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. 处理回调
// 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框架做一个简易示例:
// 使用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');
});
服务端注意事项
-
安全存储
- Client Secret必须安全存储,推荐使用环境变量
- 用户token要加密存储在数据库中
-
Token管理
- 实现token过期和刷新机制
- 定期清理无效token
-
错误处理
- 完善的错误日志记录
- 友好的错误提示
-
并发控制
- 防止重复授权请求
- 使用Redis等缓存提高性能
最佳实践
-
错误处理:实现完善的错误处理机制,为用户提供清晰的错误提示。
-
Loading状态:在授权过程中显示loading状态,提升用户体验。
-
Token管理:合理管理access token的存储和刷新机制。
-
用户体验:提供清晰的登录按钮和流程提示。
总结
Github OAuth登录的实现并不复杂,关键是要理解OAuth2.0的基本流程,注意安全性问题,并做好错误处理和用户体验优化。通过以上步骤,你就可以为你的应用添加Github登录功能了。
本文主要介绍的是重前端的方式来实现这个,但真实项目中这些事项更应该放在服务端进行,后续有机会再分享重服务端的实现。