如何设置没有过期日期的 cookies 和自定义 cookie 头?
默认情况下,cookies 在会话结束时会过期,所以用户每次关闭浏览器后都需要重新登录。但是如果想要有一个 记住我
的选项,怎么才能设置一个没有过期时间的 cookie 呢?我试着在 development.ini 文件中添加 session.cookie_expires = False
,但没有效果。
还有一个问题:怎么设置自定义的 cookie 头(比如说 lang
这个主 cookie 也没有过期时间)呢?
编辑:
我发现了 max_age
参数在 pyramid.authentication.AuthTktAuthenticationPolicy 中,它可以让你在会话之间保存一个 cookie。但是当 max_age
在 __init__.py
(配置)文件中定义时,怎么实现 记住我
的复选框呢?因为 记住我
还必须在登录视图中定义。
3 个回答
我在找类似的解决办法。我正在使用 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 日过期。
这不是正确的方法,但可以用。
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()
“记住我”这个功能的意思是,它可以在用户登录和会话之间保持有效。实现这个功能的最好方法是使用一个单独的cookie,当用户勾选这个选项时就可以设置它。如果“记住我”的意思是说应用程序在过期后应该自动登录用户,那么你可以存储一个永不过期的签名cookie。当应用程序因为用户没有登录而出现HTTPForbidden
错误时,你可以检查这个cookie,看到用户希望被记住,就可以把他们重新登录,并把他们导回到他们想去的地方。这只是一个选择,具体要看你对“记住我”的理解。
配置Pyramid的默认会话工厂
如果你使用的是UnencryptedCookieSessionFactoryConfig
会话工厂,那么你需要为cookie_max_age
参数传递一个合适的值。超时参数也会被检查,这个参数是存储在cookie中的一个签名时间戳。结合max_age,实际的会话过期时间将是max_age和超时中的较小值。
创建自定义Cookies
要设置一个自定义的cookie,你只需要调用response.set_cookie()
并传入你想要的参数。如果你使用的是渲染器,那么可以通过request.response
访问到使用的响应对象。否则,如果你是手动创建响应对象,那么就在那个地方设置它。