gpt4 book ai didi

python-3.x - 浏览器 Cookie 永不过期

转载 作者:行者123 更新时间:2023-12-03 08:01:24 30 4
gpt4 key购买 nike

我第一次实现使用 HTTPOnly Cookie 的登录身份验证。就我而言,当用户使用 fastapi 和 uvicorn 在 Python 服务 中调用登录方法时,它会创建 cookie。

我已阅读MDN文档来实现expires属性,因此,浏览器会在时间到期时删除此cookie。

我已经在 Python 中使用 http.cookies 和 Morsel 实现了 Cookie。像这样应用 HttpOnly 属性:

from http import cookies
from fastapi import FastAPI, Response, Cookie, Request
from fastapi.responses import HTMLResponse, FileResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates

mytoken = 'blablabla'

def getUtcDate():
sessionDate = datetime.now()
sessionDate += timedelta(minutes=2)
return sessionDate.strftime('%a, %d %b %Y %H:%M:%S GMT')

@app.get('cookietest')
def getCookie(response: Response):
cookie = cookies.Morsel()
cookie['httponly'] = True
cookie['version'] = '1.0.0'
cookie['domain'] = '127.0.0.1'
cookie['path'] = '/'
cookie['expires'] = getUtcDate()
cookie['max-age'] = 120
cookie['samesite'] = 'Strict'
cookie.set("jwt", "jwt", mytoken)

response.headers.append("Set-Cookie", cookie.output())

return {'status':'ok'}

这样做,当我调用“cookietest”端点时,Cookie 在浏览器中看起来正确,证据:

Cookie with expiration date

如图所示,Cookie 在 Expires/Max-Age 中有一个过期日期时间:“Wed, 12 Oct 2022 11:24:58 GMT”,登录后 2 分钟(如果用户在 14 点登录) :05:00,cookie 于 14:07:00 过期)

我的问题是超过过期时间后任何浏览器都不会删除cookie,所以这让我感到困惑。如果我过了几分钟然后向另一个端点(如 http://127.0.0.1:8000/info )发出请求,则 cookie 仍然存在于 http header 中。

有什么问题吗?我做错了什么?我正在阅读大量有关 cookie 存储和过期的文档,但我看不到任何有关此问题的信息。

非常感谢,问候

已编辑:问题已解决

Chris说,使用 FastApi 中的 set_cookie 方法解决了问题。

我仍然想知道为什么MSD文档指示日期格式必须是特定的格式,这不会导致浏览器删除Cookie,但指示以秒为单位的时间可以正常工作。

@app.get("/cookietest")
async def cookietest(response: Response):
response.set_cookie(
key='jwt',
value=getToken(),
max_age=120,
expires=120,
path='/',
secure=False,
httponly=True,
samesite="strict",
domain='127.0.0.1'
)
return {"Result": "Ok"}

最佳答案

使用expires标志时,日期必须完全采用您当前使用的格式,并且采用GMT(格林威治标准时间)时区。您的 cookie 在创建 2 分钟后不会过期的原因是您正在使用 datetime.now() ,返回当前本地日期和时间。

因此,例如,如果您当前的本地时区是 GMT+2,时间是 20:30:00(因此,GMT时间是18:30:00),创建一个在20:32:00 GMT过期的cookie实际上会告诉浏览器在2小时2分钟后删除这个cookie (从创建之时起)。如果您在浏览器的 DevTools 中查看 cookie 的 Expires/Max-Age 列(例如,在 Chrome 上,转到 DevTools 中的 Network 选项卡,单击请求的名称并然后在 Cookies 选项卡上),您会注意到日期时间末尾有一个 Z,这意味着 UTC(协调世界时)即,与 UTC 的偏移量为零时-分-秒。您还可以检查响应 header ,在其中您可以看到 Cookie 的 expires 标志设置为 20:32:00 GMT。没有明显的time difference between UTC and GMT (如果您想了解更多关于它们的差异,请查看此 post)。

因此,您可以将 .now() 替换为 .utcnow()在您的代码中:

from datetime import timedelta, datetime

def get_expiry():
expiry = datetime.utcnow()
expiry += timedelta(seconds=120)
return expiry.strftime('%a, %d-%b-%Y %T GMT')

或使用time.gmtime() ,将 time.time() 作为 secs 参数传递(返回以秒为单位的时间)加上所需的租用时间(以秒为单位):

import time

def get_expiry():
lease = 120 # seconds
end = time.gmtime(time.time() + lease)
return time.strftime('%a, %d-%b-%Y %T GMT', end)

对于上述两种方法,请使用:

cookie['expires'] = get_expiry()

您还可以使用未记录的方式直接以秒为单位传递到期时间。例如:

cookie['expires'] = 120

expires 的替代方法是 max-age 标志,它指定 cookie 从当前时刻开始的过期时间(以秒为单位)(与上面的方式类似)。如果设置为零或负值,则 cookie 将被立即删除。示例:

cookie['max-age'] = 120

注意:

如果同时设置了 expiresmax-age,则 max-age 优先(请参阅相关 documentation on MDN )。

此外,根据RFC 6265 :

4.1.2.1. The Expires Attribute

The Expires attribute indicates the maximum lifetime of the cookie,represented as the date and time at which the cookie expires. The useragent is not required to retain the cookie until the specified datehas passed. In fact, user agents often evict cookies due to memorypressure or privacy concerns.

4.1.2.2. The Max-Age Attribute

The Max-Age attribute indicates the maximum lifetime of the cookie,represented as the number of seconds until the cookie expires. Theuser agent is not required to retain the cookie for the specifiedduration. In fact, user agents often evict cookies due to memorypressure or privacy concerns.

NOTE: Some existing user agents do not support the Max-Age 
attribute. User agents that do not support the Max-Age attribute
ignore the attribute.

If a cookie has both the Max-Age and the Expires attribute, theMax-Age attribute has precedence and controls the expiration date ofthe cookie. If a cookie has neither the Max-Age nor the Expiresattribute, the user agent will retain the cookie until "the currentsession is over" (as defined by the user agent).

另请注意,如 MDN documentation 中所述关于expires标志:

Warning: Many web browsers have a session restore feature that will save all tabs and restore them the next time the browser is used.Session cookies will also be restored, as if the browser was neverclosed.

另一件事需要注意的是,自 2022 年 9 月以来,Chrome limits the cookie's max-age to 400 days :

When cookies are set with an explicit Expires/Max-Age attribute thevalue will now be capped to no more than 400 days in the future.Previously, there was no limit and cookies could expire as much asmultiple millennia in the future.

使用 FastAPI/Starlette

还应该注意的是,FastAPI/Starlette 提供了一种更简单的方法来在 Response 对象上设置 cookie,使用 set_cookie方法,如 this answer 中所述。根据Starlette documentation :

  • max_age - An integer that defines the lifetime of the cookie in seconds. A negative integer or a value of 0 will discardthe cookie immediately. Optional
  • expires - An integer that defines the number of seconds until the cookie expires. Optional

示例来自FastAPI documentation :

from fastapi import FastAPI, Response

app = FastAPI()

@app.post('/')
def create_cookie(response: Response):
response.set_cookie(key='token', value='token-value', max_age=120, expires=120, httponly=True)
return {'message': 'success'}

关于python-3.x - 浏览器 Cookie 永不过期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74041393/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com