FastAPI:注销后删除 cookie 不起作用
FastAPI: Deleting cookies after logout not working
我尝试使用 FastAPI 实现基于 OAuth2 Cookie 的身份验证。
在调用 /auth/token
端点时,它完美地设置了一个 HttpOnly cookie,如下所示:
@router.post("/auth/token", response_model=Token)
async def get_token(response: Response, form_data: OAuth2PasswordRequestForm = Depends()):
user = await authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password")
access_token_expires = timedelta(minutes=Config.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.email_id}, expires_delta=access_token_expires
)
response.set_cookie(key="access_token", value=access_token, httponly=True)
return {"access_token": access_token, "token_type": "bearer"}
同样,它应该在调用 /logout
端点后立即删除该 cookie,如下所示:
@router.get("/logout")
async def logout(request: Request, response: Response, current_user: User = Depends(get_current_active_user)):
# Also tried following two comment lines
# response.set_cookie(key="access_token", value="", max_age=1)
# response.delete_cookie("access_token", domain="localhost")
response.delete_cookie("access_token")
return templates.TemplateResponse("login.html", {"request": request, "title": "Login", "current_user": AnonymousUser()})
问题: 在调用 /logout
端点后,它应该删除它所做的 cookie,但是当我再次单击 /login
时,它能够检索具有相同身份验证令牌的相同 cookie,即浏览器在请求中发送相同的 cookie 和身份验证令牌。
这里是删除cookies后响应的调试状态。它已从响应对象中删除了 cookie,这很好:
这是我尝试登录时请求的调试状态注销后。它仍然能够从浏览器检索该 cookie:
关于如何正确删除 cookie 以便在注销后无法再次找到它的任何帮助?
问题在于响应 /logout
端点正在返回。
如下图,response.delete_cookies(key="access_token")
行能够成功删除cookie
在返回时创建 TemplateResponse 对象时,它会创建一个新的响应,从请求中复制相同的 cookie,并在某种程度上隐藏我们所做的更改(删除 cookie)。因此交换 logout()
函数中的最后两行可以解决问题:
@router.get("/logout")
async def logout(request: Request, response: Response, current_user: User = Depends(get_current_active_user)):
# Also tried following two comment lines
# response.set_cookie(key="access_token", value="", max_age=1)
# response.delete_cookie("access_token", domain="localhost")
response = templates.TemplateResponse("login.html", {"request": request, "title": "Login", "current_user": AnonymousUser()})
response.delete_cookie("access_token")
return response
我尝试使用 FastAPI 实现基于 OAuth2 Cookie 的身份验证。
在调用 /auth/token
端点时,它完美地设置了一个 HttpOnly cookie,如下所示:
@router.post("/auth/token", response_model=Token)
async def get_token(response: Response, form_data: OAuth2PasswordRequestForm = Depends()):
user = await authenticate_user(form_data.username, form_data.password)
if not user:
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect username or password")
access_token_expires = timedelta(minutes=Config.ACCESS_TOKEN_EXPIRE_MINUTES)
access_token = create_access_token(
data={"sub": user.email_id}, expires_delta=access_token_expires
)
response.set_cookie(key="access_token", value=access_token, httponly=True)
return {"access_token": access_token, "token_type": "bearer"}
同样,它应该在调用 /logout
端点后立即删除该 cookie,如下所示:
@router.get("/logout")
async def logout(request: Request, response: Response, current_user: User = Depends(get_current_active_user)):
# Also tried following two comment lines
# response.set_cookie(key="access_token", value="", max_age=1)
# response.delete_cookie("access_token", domain="localhost")
response.delete_cookie("access_token")
return templates.TemplateResponse("login.html", {"request": request, "title": "Login", "current_user": AnonymousUser()})
问题: 在调用 /logout
端点后,它应该删除它所做的 cookie,但是当我再次单击 /login
时,它能够检索具有相同身份验证令牌的相同 cookie,即浏览器在请求中发送相同的 cookie 和身份验证令牌。
这里是删除cookies后响应的调试状态。它已从响应对象中删除了 cookie,这很好:
这是我尝试登录时请求的调试状态注销后。它仍然能够从浏览器检索该 cookie:
关于如何正确删除 cookie 以便在注销后无法再次找到它的任何帮助?
问题在于响应 /logout
端点正在返回。
如下图,response.delete_cookies(key="access_token")
行能够成功删除cookie
在返回时创建 TemplateResponse 对象时,它会创建一个新的响应,从请求中复制相同的 cookie,并在某种程度上隐藏我们所做的更改(删除 cookie)。因此交换 logout()
函数中的最后两行可以解决问题:
@router.get("/logout")
async def logout(request: Request, response: Response, current_user: User = Depends(get_current_active_user)):
# Also tried following two comment lines
# response.set_cookie(key="access_token", value="", max_age=1)
# response.delete_cookie("access_token", domain="localhost")
response = templates.TemplateResponse("login.html", {"request": request, "title": "Login", "current_user": AnonymousUser()})
response.delete_cookie("access_token")
return response