每次我成功登录并想要重定向到 /welcome 时,我都会收到错误消息,但不知道为什么。
这是我的代码:
import secrets
from typing import Dict
from fastapi import FastAPI, HTTPException, status, Depends, Cookie, Form, Response, Request
from pydantic import BaseModel
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from fastapi.security import HTTPBasic, HTTPBasicCredentials
from hashlib import sha256
app = FastAPI()
security = HTTPBasic()
app.secret_key = "very constatn and random secret, best 64 characters"
app.sessions= []
@app.get("/welcome")
def welcome(request: Request, token = Cookie(None)):
if token in app.sessions:
return {"message": "No hej"}
else:
raise HTTPException(status_code=401, detail="Login first")
@app.post("/login")
def Login(response: Response,credentials: HTTPBasicCredentials = Depends(security)):
correct_username = secrets.compare_digest(credentials.username, "root")
correct_password = secrets.compare_digest(credentials.password, "toor")
if (correct_username and correct_password):
session_token = sha256(bytes(f"{credentials.username}{credentials.password}{app.secret_key}", encoding='utf8')).hexdigest()
response.status_code = status.HTTP_302_FOUND
response.set_cookie(key="session_token", value=session_token)
app.sessions += session_token
response.headers['Location'] = "/welcome"
return response
else:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Incorrect login or password",
)
这是错误消息:
response.set_cookie(key="session_token", value=session_token)
AttributeError: 'Response' object has no attribute 'set_cookie'
登录后在 /docs 中我得到:
500 Internal Server Error
如果我将 /login 从 POST 切换为 GET,登录后显示:
{"detail":[{"loc":["body","response"],"msg":"field required","type":"value_error.missing"}]}
有什么建议吗?
我认为在
RedirectResponse
中使用 fastapi.responses
是有效的。
如果我正确理解你想要实现的目标,那就是: https://en.wikipedia.org/wiki/Post/Redirect/Get
并且
RedirectResponse
允许这样做:
https://fastapi.tiangolo.com/advanced/custom-response/#redirectresponse
但是,
RedirectResponse
的默认状态代码是307
。这意味着如果您发出 GET
请求,重定向也将是 GET
请求。而且,如果您发出 POST
请求,重定向也将是 POST
请求。 (我对此进行了测试。)但是,如果您将代码更改为 303
,则 POST
请求将在重定向时变成 GET
请求。
我简化了您的代码,以下内容似乎有效:
app = FastAPI()
session_token = "abc"
@app.get("/welcome")
def welcome():
return {"message": "No hej"}
@app.post("/login")
def Login():
rr = RedirectResponse('/welcome', status_code=303)
rr.set_cookie(key="session_token", value=session_token)
return rr
我在使用gunicorn 和uvicorn 的Ubuntu 服务器上遇到了同样的问题。 HTTP 中一切都很好。当我添加 SSL 证书时,我会在重定向中收到错误。在 FastAPI 课程代码中使用 @Michael Kennedy 解决方案解决了:
response = RedirectResponse('/main', status_code=status.HTTP_302_FOUND)
return response
如果设置cookie:
@api.get('/auth_cookie')
def auth_cookie(response: Response, val):
'''set an auth cookie
'''
# IMPORTANT: httponly=True is important for server, but does not work localhost
response.set_cookie(my_cookie, val, secure=False,
httponly=False, samesite='Lax')
# then later, in your endpoint:
response = RedirectResponse('/main', status_code=status.HTTP_302_FOUND)
auth_cookie(response, access_token)
return response
这是到获取端点的重定向。我不相信这适用于帖子。
我也有同样的问题。我用这种方式解决了
response_data = response_token.json()
if response_data["token_type"] == 'Bearer':
response = RedirectResponse(url="/whoami/", status_code=303)
# Set cookies here
response.set_cookie(key="token", value=response_data["token"], max_age= response_data["expires_in"], httponly=True, secure=True, samesite='Lax')
return response
else:
raise HTTPException(status_code=403, detail="Wrong authentication method")
重要