通过请求验证 FastAPI 会话

Authenticating FastAPI session via requests

我正在按照 fastapi docs 实施用户身份验证系统。这是 app.py 的最小示例:

# import lines and utilities omitted
@app.post("/token", response_model=Token)
async def login_for_access_token(form_data: OAuth2PasswordRequestForm = Depends()):
    user = authenticate_user(form_data.username, form_data.password)
    if not user:
        raise HTTPException(
            status_code=status.HTTP_401_UNAUTHORIZED,
            detail="Incorrect username or password",
            headers={"WWW-Authenticate": "Bearer"},
        )
    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
    access_token = create_access_token(
        data={"sub": user.username}, expires_delta=access_token_expires
    )
    return {"access_token": access_token, "token_type": "bearer"}


@app.get("/user/me", response_model=UserRead)
def read_user(*, session=Depends(get_session), current_user=Depends(get_current_user)):
    user = session.get(User, current_user.username)
    if not user:
        raise HTTPException(status_code=404, detail="User not found")
    return user

当用户调用 /users/me 时,它 returns 当前用户。正如 SwaggerUI 中的教程中所述,这完全可以正常工作。但是,我无法通过 python 请求执行相同的授权和操作。这是我使用的以下 python 代码:

import requests
backend_url = "http://localhost:8000/"
login_data =  {'username':'user1', 'password':'secret1'}
s = requests.Session()
s.post(backend_url + "token", login_data) # response 200
s.get(backend_url + "user/me") # response 401

我正在寻找一些方法来重用 fastapi 返回的 access_token

您没有使用会话变量 s = requests.Session() 发送 HTTP 请求。 所以 post 和 get 方法是相互独立发送的。 尝试使用

s = requests.Session()
s.post(backend_url + "token", login_data)  # use the session post method

s.get(backend_url + "user/me")  # use the session get method

我在fastapi本身的docs中找到了答案:

import requests

backend_url = "http://localhost:8000/"
login_data =  {'username':'user1', 'password':'secret1'}

session = requests.Session()
response = session.post(backend_url + "token", login_data)
response = json.loads(response.content.decode('utf-8'))

session.headers.update({"Authorization": 'Bearer ' + response['access_token']})

session.get(backend_url + "user/me")