FastApi BasicAuth 与 cookies 重定向问题

问题描述 投票:0回答:3

每次我成功登录并想要重定向到 /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"}]}

有什么建议吗?

python cookies response fastapi
3个回答
3
投票

我认为在

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

0
投票

我在使用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


这是到获取端点的重定向。我不相信这适用于帖子。


0
投票

我也有同样的问题。我用这种方式解决了

    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")

重要

  1. 您需要返回设置 Cookie 的同一对象
  2. 您应该在设置Cookie之前定义重定向响应
© www.soinside.com 2019 - 2024. All rights reserved.