title: 如何在FastAPI中玩转GitHub认证,让用户一键登录?

date: 2025/06/22 09:11:47

updated: 2025/06/22 09:11:47

author: cmdragon

excerpt:

GitHub第三方认证集成通过OAuth2.0授权码流程实现,包含用户跳转GitHub认证、获取授权码、交换访问令牌及调用API获取用户信息四个步骤。首先需在GitHub注册应用,获取CLIENT_ID和CLIENT_SECRET。使用FastAPI实现认证流程,包括初始化认证、处理回调、生成JWT令牌及验证用户。安全措施包括使用state参数防止CSRF攻击和正确配置Authorization头。常见问题如redirect_uri不匹配、invalid_state错误和JWT解码失败,需检查回调地址、state一致性和SECRET_KEY配置。

categories:

  • 后端开发
  • FastAPI

tags:

  • GitHub认证
  • OAuth2.0
  • FastAPI
  • JWT
  • 第三方登录
  • 安全增强
  • 认证流程


扫描二维码

关注或者微信搜一搜:编程智域 前端至全栈交流与成长

发现1000+提升效率与开发的AI工具和实用程序https://tools.cmdragon.cn/

一、GitHub第三方认证集成原理与实践

1. OAuth2.0流程解析

在FastAPI中集成GitHub认证需要理解OAuth2.0授权码流程,该流程包含四个核心步骤:

  1. 前端引导用户跳转到GitHub认证页面
  2. GitHub返回授权码到回调地址
  3. 后端用授权码交换访问令牌
  4. 使用令牌访问GitHub API获取用户信息

整个过程如同酒店入住流程:用户出示身份证(GitHub登录)→ 获得临时房卡(授权码)→ 换取正式房卡(访问令牌)→ 享受酒店服务(API调用)

2. GitHub应用注册

在实施前需要完成GitHub应用注册:

  1. 访问 GitHub Developer Settings
  2. 创建新OAuth应用
  3. 填写应用信息(重要参数):

获取关键凭证:

CLIENT_ID = "your_github_client_id"
CLIENT_SECRET = "your_github_client_secret"

3. 环境配置

安装所需依赖(推荐使用虚拟环境):

pip install fastapi==0.103.1 uvicorn==0.23.2 python-multipart==0.0.6 httpx==0.25.0 python-jose[cryptography]==3.3.0

4. 认证流程实现

完整认证代码示例:

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import OAuth2AuthorizationCodeBearer
from jose import JWTError, jwt
from pydantic import BaseModel
import httpx app = FastAPI() # 配置模型
class AuthConfig(BaseModel):
client_id: str = CLIENT_ID
client_secret: str = CLIENT_SECRET
redirect_uri: str = "http://localhost:8000/auth/github/callback"
token_url: str = "https://github.com/login/oauth/access_token"
user_url: str = "https://api.github.com/user" # JWT配置
SECRET_KEY = "your-secret-key-123"
ALGORITHM = "HS256" oauth2_scheme = OAuth2AuthorizationCodeBearer(
authorizationUrl="https://github.com/login/oauth/authorize",
tokenUrl="https://github.com/login/oauth/access_token"
) @app.get("/auth/github")
async def github_login():
"""初始化GitHub认证流程"""
return {
"auth_url": f"https://github.com/login/oauth/authorize?client_id={CLIENT_ID}"
} @app.get("/auth/github/callback")
async def github_callback(code: str):
"""处理GitHub回调"""
async with httpx.AsyncClient() as client:
# 交换访问令牌
token_response = await client.post(
"https://github.com/login/oauth/access_token",
data={
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"code": code
},
headers={"Accept": "application/json"}
) access_token = token_response.json().get("access_token")
if not access_token:
raise HTTPException(status_code=400, detail="认证失败") # 获取用户信息
user_response = await client.get(
"https://api.github.com/user",
headers={"Authorization": f"Bearer {access_token}"}
) user_data = user_response.json()
return generate_jwt(user_data) def generate_jwt(user_data: dict):
"""生成JWT令牌"""
token_data = {
"sub": user_data["login"],
"id": user_data["id"],
"avatar": user_data["avatar_url"]
}
return {
"access_token": jwt.encode(token_data, SECRET_KEY, algorithm=ALGORITHM),
"token_type": "bearer"
} async def get_current_user(token: str = Depends(oauth2_scheme)):
"""JWT验证依赖项"""
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
return payload
except JWTError:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="无效的凭证",
headers={"WWW-Authenticate": "Bearer"},
) @app.get("/protected")
async def protected_route(user: dict = Depends(get_current_user)):
"""需要认证的端点示例"""
return {"message": f"欢迎,{user['sub']}!"}

5. 安全增强措施

在正式环境中必须配置以下安全参数:

# 在AuthConfig中添加
state: str = "random_anti_csrf_string"
scope: str = "user:email" # 修改认证URL
auth_url = f"https://github.com/login/oauth/authorize?client_id={CLIENT_ID}&state={state}&scope={scope}"

6. 课后Quiz

  1. 为什么在OAuth流程中需要使用state参数?

    A. 提高请求速度

    B. 防止CSRF攻击

    C. 存储用户信息

    D. 加密通信内容

答案:B。state参数用于防止跨站请求伪造攻击,服务器会验证请求和回调中的state值是否一致。

  1. 以下哪个HTTP头对防范安全漏洞最关键?

    A. Accept-Encoding

    B. Content-Type

    C. Authorization

    D. User-Agent

答案:C。Authorization头正确携带Bearer token是保证认证安全的关键,需要配合HTTPS使用。

7. 常见报错解决方案

问题1:redirect_uri_mismatch

error=redirect_uri_mismatch&error_description=The+redirect_uri+MUST+match...

解决方案:

  1. 检查GitHub应用设置中的回调地址
  2. 确保请求参数中的redirect_uri与注册地址完全一致
  3. 本地开发时使用http://localhost:8000前缀

问题2:invalid_state参数错误

解决方案:

  1. 确保前端传递的state参数与后端验证值一致
  2. 使用加密安全的随机数生成state
  3. 设置合理的state有效期(建议5分钟)

问题3:JWT解码失败

jose.exceptions.JWTError: Signature verification failed

解决方案:

  1. 检查SECRET_KEY是否一致
  2. 验证令牌是否过期
  3. 确认算法设置(ALGORITHM)匹配

余下文章内容请点击跳转至 个人博客页面 或者 扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长,阅读完整的文章:如何在FastAPI中玩转GitHub认证,让用户一键登录? | cmdragon's Blog

往期文章归档:

如何在FastAPI中玩转GitHub认证,让用户一键登录?的更多相关文章

  1. Python_socket常见的方法、网络编程的安全注意事项、socketsever模块、浏览器中在一段时间记录用户的登录验证机制

    1.socket常见的方法 socket_常见方法_服务器端 import socket from socket import SOL_SOCKET,SO_REUSEADDR sk = socket. ...

  2. 如何在 Linux 中配置基于密钥认证的 SSH

    什么是基于 SSH 密钥的认证? 众所周知,Secure Shell,又称 SSH,是允许你通过无安全网络(例如 Internet)和远程系统之间安全访问/通信的加密网络协议.无论何时使用 SSH 在 ...

  3. 如何在Loadrunner11中解决HTTP BASIC认证登录报401的问题

    在对Carte+kettle的性能测试过程中,通过在loadrunner中用web_set_user("cluster", "cluster","17 ...

  4. 如何在ChemDraw中打出符号π

    很多人日常使用ChemDraw是一款非常优秀的化学绘图软件,在其绘制化学结构式或者反应式的过程中,常常需要添加各种符号.比如有的用户会需要输入希腊字符π,但是不知道用什么方法添加.本教程就来给大家介绍 ...

  5. 如何在 Kubernetes 集群中玩转 Fluid + JuiceFS

    作者简介: 吕冬冬,云知声超算平台架构师, 负责大规模分布式机器学习平台架构设计与功能研发,负责深度学习算法应用的优化与 AI 模型加速.研究领域包括高性能计算.分布式文件存储.分布式缓存等. 朱唯唯 ...

  6. 如何在linux中部署mongodb并设置连接认证

    在windows上给mongodb设置连接认证权限:mongodb默认是不认证的,默认没有账号,现在就讲讲怎么设置账户和密码 1.首先进入C:\mongodb\bin下面双击运行mongo.exe启动 ...

  7. Android Studio中Git和GitHub使用详解

    一.Git和GitHub简述 1.Git 分布式版本控制系统,最先使用于Linux社区,是一个开源免费的版本控制系统,功能类似于SVN和CVS.Git与其他版本管理工具最大的区别点和优点就是分布式: ...

  8. 一次 .NET Core 中玩锁的经历:ManualResetEventSlim, Semaphore 与 SemaphoreSlim

    最近同事对  .net core memcached 缓存客户端 EnyimMemcachedCore 进行了高并发下的压力测试,发现在 linux 上高并发下使用 async 异步方法读取缓存数据会 ...

  9. 我是如何在SQLServer中处理每天四亿三千万记录的

    首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文中有不对的地方,请各位数据库大牛给予指正,以便我能够更好的处理此次业务. ...

  10. 【转】我是如何在SQLServer中处理每天四亿三千万记录的

    原文转自:http://blog.jobbole.com/80395/ 首先声明,我只是个程序员,不是专业的DBA,以下这篇文章是从一个问题的解决过程去写的,而不是一开始就给大家一个正确的结果,如果文 ...

随机推荐

  1. 学习 Docker 如何查看镜像信息?

    学习 Docker 如何查看镜像信息? 一.images 命令列出镜像 通过使用如下两个命令,列出本机已有的镜像: docker images 或: docker image ls 如下图所示: 对上 ...

  2. Linux下安装node及npm

    Linux下安装node 1.解压 $ tar zxf node-v8.9.0-linux-x64.tar.gz 2.移动到指定目录 $ mv node-v8.9.0-linux-x64 /usr/l ...

  3. 【跟K8S学设计】Informer全分析-Reflector(上)

    鉴于Informer架构及其处理逻辑蕴含了丰富的实战技术,本文将分为上下两章进行深入探讨. 上篇将专注于解析Informer中的Reflector组件,而下篇则会详尽分析Indexer模块.通过这种结 ...

  4. 理解tomcat中的BIO、NIO、AIO、ARP

    理解tomcat中的BIO.NIO.AIO.ARP tomcat作为springboot中默认的web容器,了解tomcat的运转可以帮助我们更好的去调整tomcat的参数达到更好的性能 前置知识 I ...

  5. 超实用!用FunctionCall实现快递AI助手

    昨天晚上直播,我们用 RAG(Retrieval-Augmented Generation,检索增强生成)实现了数据库 AI 助手,今天我们准备换一个技术使用 function call 来实现快递 ...

  6. 查看MySQL是否安装成功

    1)安装了Windows Service:MySQL80,并且已经启动. 2)安装了MySQL软件.安装位置为:C:\Program Files\MySQL  (默认路径) (MySQL文件下放的是软 ...

  7. Java高效合并Excel报表实战:GcExcel让数据处理更简单

    前言:为什么需要自动化合并Excel? 在日常办公场景中,Excel报表合并是数据分析的基础操作.根据2023年企业办公效率报告显示: 财务人员平均每周花费6.2小时在Excel合并操作上 人工合并的 ...

  8. GSLibrary平台本地搭建(windows)

    一.安装配置数据库 https://dev.mysql.com/downloads/windows/installer/5.7.html 创建GSLibrary数据库 mysql -uroot -p ...

  9. 使用IDEA管理服务器Docker及远程仓库

    目录 配置连接Docker服务器及远程仓库 连接服务器Docker 远程仓库(可选) IDEA管理 确保docker服务器已经开启了远程守护进程访问.[1] 配置连接Docker服务器及远程仓库 连接 ...

  10. linux vim增强使用

    目录 删除 编辑 删除 删除当前行 dd 删除当前行后面的所有行 dG 编辑 恢复为未修改前的状态 uu