如何设置没有过期日期的 cookies 和自定义 cookie 头?

0 投票
3 回答
5643 浏览
提问于 2025-04-17 09:34

默认情况下,cookies 在会话结束时会过期,所以用户每次关闭浏览器后都需要重新登录。但是如果想要有一个 记住我 的选项,怎么才能设置一个没有过期时间的 cookie 呢?我试着在 development.ini 文件中添加 session.cookie_expires = False,但没有效果。

还有一个问题:怎么设置自定义的 cookie 头(比如说 lang 这个主 cookie 也没有过期时间)呢?

编辑:

我发现了 max_age 参数在 pyramid.authentication.AuthTktAuthenticationPolicy 中,它可以让你在会话之间保存一个 cookie。但是当 max_age__init__.py(配置)文件中定义时,怎么实现 记住我 的复选框呢?因为 记住我 还必须在登录视图中定义。

3 个回答

0

我在找类似的解决办法。我正在使用 bottle-cork.py 来进行用户认证,需要一个选项让用户选择“保持我登录状态”。

from bottle, import request, response # etc...

def post_get(name, default=''):
    return bottle.request.POST.get(name, default).strip()

def login():
    """Authenticate users"""
    username = post_get('username').lower()
    password = post_get('password')
    keep_login = post_get('keep_login')
    session = request.environ['beaker.session']
    if keep_login == 'true':
        session.cookie_expires = False
        response.set_cookie('keep_login', "true")
    else:
        session.cookie_expires = True
        response.set_cookie('keep_login', "false")
    aaa.login(username, password)

但是,每次向服务器发送请求时,bottle 都会返回一个新的会话 cookie,这个 cookie 默认是在浏览器关闭时过期。为了修复这个问题,我添加了一个函数,每次发送请求时都会调用这个函数:

def preserve_cookie(request):
    keep_login = request.get_cookie('keep_login')
    session = request.environ['beaker.session']
    if keep_login == 'true':
        session.cookie_expires = False
    return request

比如说:

@bottle.get('/get_username')
def check_login(user=None):
    try:
        aaa.require(username=user)
    except:
        raise bottle.HTTPError(401)
    preserve_cookie(request)
    return aaa.current_user.username

这样返回的新 cookie 就能保持用户选择的登录状态。不过,目前 beaker.SessionMiddleware 的实现方式是直接把 cookie 设置为在 2038 年 1 月 18 日过期。

0

这不是正确的方法,但可以用。

def login_user(request, usesr_id, time=None):
"""
@type request: pyramid.request.Request
@type usesr_id: int
@type time: int 
@rtype: Response
"""
request.session["user_id"] = usesr_id
if time is not None:
    request.session._sess.cookie_expires = datetime.timedelta(seconds=time)
    request.session._sess._set_cookie_expires(None)
else:
    request.session._sess.cookie_expires = True
    request.session._sess._set_cookie_expires(None)
request.session._update_cookie_out()
request.session.save()
3

“记住我”这个功能的意思是,它可以在用户登录和会话之间保持有效。实现这个功能的最好方法是使用一个单独的cookie,当用户勾选这个选项时就可以设置它。如果“记住我”的意思是说应用程序在过期后应该自动登录用户,那么你可以存储一个永不过期的签名cookie。当应用程序因为用户没有登录而出现HTTPForbidden错误时,你可以检查这个cookie,看到用户希望被记住,就可以把他们重新登录,并把他们导回到他们想去的地方。这只是一个选择,具体要看你对“记住我”的理解。

配置Pyramid的默认会话工厂

如果你使用的是UnencryptedCookieSessionFactoryConfig会话工厂,那么你需要为cookie_max_age参数传递一个合适的值。超时参数也会被检查,这个参数是存储在cookie中的一个签名时间戳。结合max_age,实际的会话过期时间将是max_age和超时中的较小值。

http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/api/session.html#pyramid.session.UnencryptedCookieSessionFactoryConfig

创建自定义Cookies

要设置一个自定义的cookie,你只需要调用response.set_cookie()并传入你想要的参数。如果你使用的是渲染器,那么可以通过request.response访问到使用的响应对象。否则,如果你是手动创建响应对象,那么就在那个地方设置它。

http://docs.pylonsproject.org/projects/pyramid/en/1.3-branch/api/response.html#pyramid.response.Response.set_cookie

撰写回答