FastAPI OAuth2 JWT令牌验证异常:无需有效令牌即可访问接口
问题分析与解决方案
问题出在你只用到了oauth2_scheme提取令牌,但没有对令牌的有效性做任何验证。
oauth2_scheme的作用仅仅是从Authorization头里提取Bearer后面的内容——哪怕后面是空字符串,它也会把空字符串作为token参数传给接口,而你的接口没有校验这个token是否合法,所以直接放行。当你去掉请求头时,oauth2_scheme会抛出未授权错误,这是它唯一执行的逻辑。
要真正保护接口,必须完成JWT的校验流程:验证token的签名、过期时间、内容合法性等。按照官方规范,你需要定义一个校验token的依赖函数,示例如下:
from jose import JWTError, jwt from fastapi import Depends, HTTPException, status # 这里用你自己的密钥和算法,要和生成token时完全一致 SECRET_KEY = "your-custom-secret-key" ALGORITHM = "HS256" async def get_current_user(token: str = Depends(oauth2_scheme)): credentials_exception = HTTPException( status_code=status.HTTP_401_UNAUTHORIZED, detail="无效的身份凭证", headers={"WWW-Authenticate": "Bearer"}, ) try: # 解码并验证token payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM]) username: str = payload.get("sub") if username is None: raise credentials_exception # 可选:根据username从数据库查询用户信息返回 except JWTError: # token签名无效、过期都会触发这个异常 raise credentials_exception return username
然后修改你的接口,用这个校验依赖代替直接使用oauth2_scheme:
@app.get("/Tables") async def tables(current_user = Depends(get_current_user)): x = ("SHOW TABLES;") db = db_conn(x) return db
这样修改后,当前端只传Bearer不带实际token时,jwt.decode会因为空字符串无法解析而抛出异常,接口会返回401未授权错误,真正实现鉴权保护。
另外补充:前端正确的请求头格式应该是Authorization: Bearer <你的实际token>,比如Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...,空的Bearer是不符合OAuth2规范的,只是因为你之前没做校验才侥幸通过。
内容的提问来源于stack exchange,提问作者Kozer H
相关产品推荐
相关产品推荐

