You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FastAPI-Login实现未登录用户重定向至登录页问题求助

问题原因

你当前代码没触发重定向,是因为fastapi_login的LoginManager在用户未认证时,会直接抛出InvalidCredentialsException或者带401状态码的HTTPException,而你的try-except块抓的是status.HTTP_401_UNAUTHORIZED(这只是个数值401),根本捕获不到实际抛出的异常,所以FastAPI会用默认逻辑返回JSON格式的401响应。

解决方案

给你两种可行的解决办法,按需选择:

方式一:全局异常处理器

通过FastAPI的异常处理器,捕获fastapi_login抛出的未认证异常,直接返回重定向。

修改后的代码:

from fastapi import (
    Depends,
    FastAPI,
    HTTPException,
    status,
    Body,
    Request
)
from fastapi.encoders import jsonable_encoder
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from fastapi.responses import HTMLResponse, RedirectResponse
import app.models as models
import app.database as database
from datetime import datetime, timedelta
from jose import JWTError, jwt
from starlette.responses import FileResponse
from fastapi_login import LoginManager
from fastapi_login.exceptions import InvalidCredentialsException, NotAuthenticatedException
from fastapi import Cookie
import re

app = FastAPI()

# 替换成你实际的密钥
SECRET_KEY = "your-actual-secret-key"
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
manager = LoginManager(SECRET_KEY, token_url="/auth/login", use_cookie=True)
manager.cookie_name = "token"

# 处理未认证异常,自动重定向到登录页
@app.exception_handler(NotAuthenticatedException)
async def auth_exception_handler(request: Request, exc: NotAuthenticatedException):
    return RedirectResponse(url="/login", status_code=status.HTTP_302_FOUND)

# 登录页路由(需要你自己实现页面内容)
@app.get("/login")
async def show_login_page():
    return FileResponse('login.html')

@app.get("/")
@app.get("/item")
async def read_index(user=Depends(manager)):
    return FileResponse('item.html')

方式二:自定义认证依赖

自己写认证逻辑的依赖函数,在里面处理认证失败的情况,直接返回重定向。

修改后的代码:

from fastapi import (
    Depends,
    FastAPI,
    HTTPException,
    status,
    Body,
    Request
)
from fastapi.encoders import jsonable_encoder
from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
from fastapi.responses import HTMLResponse, RedirectResponse
import app.models as models
import app.database as database
from datetime import datetime, timedelta
from jose import JWTError, jwt
from starlette.responses import FileResponse
from fastapi_login import LoginManager
from fastapi_login.exceptions import InvalidCredentialsException
from fastapi import Cookie
import re

app = FastAPI()

SECRET_KEY = "your-actual-secret-key"
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
manager = LoginManager(SECRET_KEY, token_url="/auth/login", use_cookie=True)
manager.cookie_name = "token"

# 自定义认证依赖,失败时重定向
async def get_authenticated_user(request: Request):
    try:
        user = await manager.get_current_user(request)
        return user
    except (InvalidCredentialsException, JWTError):
        # 通过HTTPException的headers返回重定向地址
        raise HTTPException(
            status_code=status.HTTP_302_FOUND,
            headers={"Location": "/login"}
        )

@app.get("/login")
async def show_login_page():
    return FileResponse('login.html')

@app.get("/")
@app.get("/item")
async def read_index(user=Depends(get_authenticated_user)):
    return FileResponse('item.html')
注意事项
  • 方式一适合全局统一处理所有未认证请求的跳转,方式二更灵活,可针对特定路由调整逻辑。
  • 必须确保/login路由已经实现,能正确返回登录页面,否则重定向后会出现404错误。

内容的提问来源于stack exchange,提问作者Echchama Nayak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 00:35:33