如何在FastAPI中为教师、学生配置独立的权限认证tokenUrl?
实现FastAPI多用户类型独立认证配置
要给教师和学生分别配置独立的tokenUrl,核心是为两类用户创建独立的OAuth2安全方案,并为对应路由绑定专属的认证依赖。具体实现步骤如下:
1. 定义两个独立的OAuth2认证实例
通过OAuth2PasswordBearer分别创建教师和学生的认证方案,指定不同的tokenUrl和唯一的scheme_name(确保OpenAPI能区分两个方案):
from fastapi import FastAPI, Depends, HTTPException, status from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm app = FastAPI(title="校园笔记分享平台") # 教师认证方案:tokenUrl指向教师登录接口 teacher_oauth2 = OAuth2PasswordBearer( tokenUrl="teachers/token", scheme_name="TeacherAuth", description="教师账号密码认证" ) # 学生认证方案:tokenUrl指向学生登录接口 student_oauth2 = OAuth2PasswordBearer( tokenUrl="students/token", scheme_name="StudentAuth", description="学生账号密码认证" )
2. 实现两类用户的token获取接口
分别编写教师和学生的登录接口,返回对应的认证token:
# 模拟用户数据库(真实项目替换为数据库查询) fake_teachers_db = {"teacher001": {"username": "teacher001", "password": "teach_123"}} fake_students_db = {"student001": {"username": "student001", "password": "stud_123"}} # 教师登录获取token @app.post("/teachers/token", summary="教师登录获取token") async def teacher_login(form_data: OAuth2PasswordRequestForm = Depends()): teacher = fake_teachers_db.get(form_data.username) if not teacher or teacher["password"] != form_data.password: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误", headers={"WWW-Authenticate": "Bearer"}, ) return {"access_token": teacher["username"], "token_type": "bearer"} # 学生登录获取token @app.post("/students/token", summary="学生登录获取token") async def student_login(form_data: OAuth2PasswordRequestForm = Depends()): student = fake_students_db.get(form_data.username) if not student or student["password"] != form_data.password: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="用户名或密码错误", headers={"WWW-Authenticate": "Bearer"}, ) return {"access_token": student["username"], "token_type": "bearer"}
3. 为路由绑定对应认证依赖
教师专属路由绑定teacher_oauth2依赖,学生专属路由绑定student_oauth2依赖:
# 教师专属路由:发布笔记 @app.post("/notes/", summary="发布笔记(教师专属)") async def create_note(token: str = Depends(teacher_oauth2)): return {"message": f"教师 [{token}] 发布笔记成功"} # 教师专属路由:更新笔记 @app.put("/notes/{note_id}", summary="更新笔记(教师专属)") async def update_note(note_id: int, token: str = Depends(teacher_oauth2)): return {"message": f"教师 [{token}] 更新笔记 {note_id} 成功"} # 教师专属路由:删除笔记 @app.delete("/notes/{note_id}", summary="删除笔记(教师专属)") async def delete_note(note_id: int, token: str = Depends(teacher_oauth2)): return {"message": f"教师 [{token}] 删除笔记 {note_id} 成功"} # 学生专属路由:查看笔记 @app.get("/notes/", summary="查看笔记(学生专属)") async def get_notes(token: str = Depends(student_oauth2)): return {"message": f"学生 [{token}] 查看笔记列表", "notes": ["高等数学笔记", "Python入门笔记"]}
4. 效果验证
启动服务后访问Swagger UI(默认http://localhost:8000/docs):
- 页面顶部会显示两个认证选项:
TeacherAuth和StudentAuth - 点击教师路由旁的锁按钮,弹出的登录窗口会自动使用
teachers/token作为tokenUrl - 点击学生路由旁的锁按钮,会自动使用
students/token作为tokenUrl
扩展:添加Token有效性验证(真实项目必备)
如果使用JWT等加密token,可封装专属的依赖函数验证token合法性:
async def get_current_teacher(token: str = Depends(teacher_oauth2)): # 这里添加JWT解析、用户存在性验证等逻辑 teacher = fake_teachers_db.get(token) if not teacher: raise HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="无效的教师token", headers={"WWW-Authenticate": "Bearer"}, ) return teacher # 教师路由改用该依赖 @app.post("/notes/", summary="发布笔记(教师专属)") async def create_note(current_teacher: dict = Depends(get_current_teacher)): return {"message": f"教师 [{current_teacher['username']}] 发布笔记成功"}
内容的提问来源于stack exchange,提问作者Shishir Sabbir
相关产品推荐
相关产品推荐

