Python: Flask中的GitHub OAuth
2025-02-17
概述
本指南介绍如何在 Flask 应用中集成 GitHub OAuth2.0 认证,实现以下功能:
- 使用 GitHub 账号登录
- 处理 OAuth 回调
- 管理用户会话
先决条件
- Flask 2.3.3+
- Python 3.7+
- GitHub 账号
- 基本的 Flask 开发经验
配置 GitHub OAuth
- 登录 GitHub,进入 Settings -> Developer settings -> OAuth Apps
- 点击 "New OAuth App"
- 填写应用信息:
- Application name: 你的应用名称
- Homepage URL: 应用首页地址
- Authorization callback URL: 回调地址(如 http://localhost:5000/callback)
- 创建后获取 Client ID 和 Client Secret
入门
安装依赖
pip install flask requests基础配置
from flask import Flask, redirect, request, session
import requests
import os
app = Flask(__name__)
app.secret_key = os.urandom(24)
# GitHub OAuth 配置
GITHUB_CLIENT_ID = "your_client_id"
GITHUB_CLIENT_SECRET = "your_client_secret"
GITHUB_REDIRECT_URI = "http://localhost:5000/callback"会话存储
会话管理
def get_user_from_session():
"""从会话中获取用户信息"""
return session.get('user')
def store_user_in_session(user_data):
"""存储用户信息到会话"""
session['user'] = user_data
def clear_session():
"""清除会话"""
session.clear()GitHub OAuth 实现
登录路由
@app.route('/login')
def login():
"""重定向到 GitHub 授权页面"""
return redirect(
f'https://github.com/login/oauth/authorize?'
f'client_id={GITHUB_CLIENT_ID}&'
f'redirect_uri={GITHUB_REDIRECT_URI}'
)回调处理
@app.route('/callback')
def callback():
"""处理 GitHub 回调"""
# 获取授权码
code = request.args.get('code')
if not code:
return 'Error: No code provided', 400
# 使用授权码获取访问令牌
response = requests.post(
'https://github.com/login/oauth/access_token',
data={
'client_id': GITHUB_CLIENT_ID,
'client_secret': GITHUB_CLIENT_SECRET,
'code': code
},
headers={'Accept': 'application/json'}
)
# 获取用户信息
access_token = response.json().get('access_token')
if access_token:
user_data = requests.get(
'https://api.github.com/user',
headers={'Authorization': f'token {access_token}'}
).json()
# 存储用户信息
store_user_in_session(user_data)
return redirect('/')
return 'Error: Failed to get access token', 400用户信息路由
@app.route('/user')
def user():
"""获取当前登录用户信息"""
user_data = get_user_from_session()
if user_data:
return user_data
return 'Not logged in', 401登录 github
import supabase
# 登录 github
@app.route("/signin/github")
def signin_with_github():
res = supabase.auth.sign_in_with_oauth(
{
provider": "github",
"options": {
"redirect_to": f"{request.host_url}callback"
},
}
)
return redirect(res.url)登出路由
@app.route('/logout')
def logout():
"""清除用户会话"""
clear_session()
return redirect('/')完整示例
from flask import Flask, redirect, request, session
import requests
import os
app = Flask(__name__)
app.secret_key = os.urandom(24)
# GitHub OAuth 配置
GITHUB_CLIENT_ID = os.getenv("GITHUB_CLIENT_ID")
GITHUB_CLIENT_SECRET = os.getenv("GITHUB_CLIENT_SECRET")
GITHUB_REDIRECT_URI = "http://localhost:5000/callback"
# ... 其他路由代码 ...
if __name__ == '__main__':
app.run(debug=True)最佳实践
安全性
- 使用环境变量存储敏感信息
- 实现 CSRF 保护
- 使用 HTTPS
错误处理
- 处理所有可能的错误情况
- 提供友好的错误信息
- 记录错误日志
用户体验
- 添加加载状态
- 实现记住登录状态
- 提供清晰的提示信息
注意:
- 妥善保管 Client Secret
- 注意 API 访问限制
- 定期刷新 token
- 处理会话过期