Question

By default, cookies expires at session end, so user need to login every time after closing the browser. But what about remember option - how to set cookie with no expiration date? I've tried to add session.cookie_expires = False in development.ini file, but it didn't help.

And another question: how to set custom cookie header (for example lang to main cookie with no expiration date too)?

EDIT:

I've found max_age parametr in pyramid.authentication.AuthTktAuthenticationPolicy which lets you save a cookie between sessions. But how to implement remember me checkbox when max_age defines it in __init__.py (config) file and remember me must be defined in login view?

Was it helpful?

Solution

The idea behind "remember me" is that it's an option that lasts between logins and sessions. This is best implemented as a separate cookie that you can set if the user checks the box. If "remember me" means that the application should log you back in if the policy has expired, then simply store a signed cookie that never expires. Then when the application raises an HTTPForbidden because the user isn't logged in, you can check for the cookie, see that they wanted to be remembered, log them back in, and redirect them back to where they were trying to go. That's just one option, depending on what you mean by "remember me".

Configuring Pyramid's Default Session Factory

If you are using the UnencryptedCookieSessionFactoryConfig session factory, then you need to pass an appropriate value for the cookie_max_age argument. The timeout parameter is also checked, which is a signed timestamp stored within the cookie. Combined with max_age, the actual expiration time of the session would be the minimum of max_age and timeout.

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

Creating Custom Cookies

To set a custom cookie you simply need to call response.set_cookie() with the parameters you'd like. If you are using a renderer then you can access the response object that's used via request.response. Otherwise if you are manually creating a response object yourself, just set it there.

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

OTHER TIPS

It's not correct way, but works.

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()

I was looking for a similar solution. I'm using bottle-cork.py for my user authentication and needed a way to give users the option "Keep me logged in"

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)

However, every time a request is sent to the server, bottle returns a new session cookie that defaults back to expiring when the browser closes. To fix this, I added a function that I call every time a request is sent:

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

So, for instance:

@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

This way the new cookie that is returned maintains the user's preference of keeping the login session saved. However, the way beaker.SessionMiddleware is currently implemented, it just sets the cookie to expire Jan 18, 2038.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top