我想在用户未登录时将他们重定向到登录页面。
这是我的代码:
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()
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
manager = LoginManager(SECRET_KEY, token_url="/auth/login", use_cookie=True)
manager.cookie_name = "token"
@app.get("/")
@app.get("/item")
async def read_index(user=Depends(manager)):
try:
return FileResponse('item.html')
except status.HTTP_401_UNAUTHORIZED:
return RedirectResponse(url="/login", status_code=status.HTTP_302_FOUND)
但是,当我访问此页面时:localhost:8000/item
,我得到以下信息:
{"detail":"Not authenticated"}
从您提供的代码片段来看,您似乎正在使用(第三方)FastAPI-Login https://github.com/MushroomMaula/fastapi_login包裹。他们的文档 https://fastapi-login.readthedocs.io/advanced_usage/#exception-handling建议使用自定义Exception
on the LoginManager
实例,可用于将用户重定向到login
页面,如果他们没有登录。
工作示例:
下面的认证是基于cookies https://fastapi-login.readthedocs.io/advanced_usage/#cookies,但您可以将令牌传递给Authorization
标题也是如此。导航/protected
未登录时的路由以使重定向生效。
from fastapi import FastAPI, Depends, Request, Response, status
from starlette.responses import RedirectResponse, HTMLResponse, JSONResponse
from fastapi.security import OAuth2PasswordRequestForm
from fastapi_login.exceptions import InvalidCredentialsException
from fastapi_login import LoginManager
class NotAuthenticatedException(Exception):
pass
app = FastAPI()
SECRET = "super-secret-key"
manager = LoginManager(SECRET, '/login', use_cookie=True, custom_exception=NotAuthenticatedException)
DB = {
'users': {
'[email protected] /cdn-cgi/l/email-protection': {
'name': 'John Doe',
'password': 'hunter2'
}
}
}
def query_user(user_id: str):
return DB['users'].get(user_id)
@manager.user_loader()
def load_user(user_id: str):
user = DB['users'].get(user_id)
return user
@app.exception_handler(NotAuthenticatedException)
def auth_exception_handler(request: Request, exc: NotAuthenticatedException):
"""
Redirect the user to the login page if not logged in
"""
return RedirectResponse(url='/login')
@app.get("/login", response_class=HTMLResponse)
def login_form():
return """
<!DOCTYPE html>
<html>
<body>
<form method="POST" action="/login">
<label for="username">Username:</label><br>
<input type="text" id="username" name="username" value="[email protected] /cdn-cgi/l/email-protection"><br>
<label for="password">Password:</label><br>
<input type="password" id="password" name="password" value="hunter2"><br><br>
<input type="submit" value="Submit">
</form>
</body>
</html>
"""
@app.post('/login')
def login(data: OAuth2PasswordRequestForm = Depends()):
email = data.username
password = data.password
user = query_user(email)
if not user:
# you can return any response or error of your choice
raise InvalidCredentialsException
elif password != user['password']:
raise InvalidCredentialsException
token = manager.create_access_token(data={'sub': email})
response = RedirectResponse(url="/protected",status_code=status.HTTP_302_FOUND)
manager.set_cookie(response, token)
return response
@app.get('/protected')
def protected_route(user=Depends(manager)):
return {'user': user}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)