Symfony2 – remember me cookies

Featured Image © hoefi@sxc.hu

When developing web services for mobile devices to handle user log-in, I had to make it persistent somehow, so the user should not log-in each time when starts mobile application, but I rather wanted log in to be permanent somehow while user does not log-out manually.
Because we used form based authentication with cookies, the cookie with PHPSESSID was always set, but it was not guarantee that user session will not expire sometimes.
I wanted avoid that and that’s why I implemented native Symfony’s ‘remember me’ functionality inside project.

config.yml

#...

framework:
    secret:          %secret%
    charset:         UTF-8
    router:          { resource: "%kernel.root_dir%/config/routing.yml" }
    form:            true
    csrf_protection: true
    #validation:      true
    validation:      { enable_annotations: true }
    templating:      { engines: ['twig'] } #assets_version: SomeVersionScheme
    translator:    { fallback: en }
    session:
        default_locale: %locale%
        lifetime:       31536000
        auto_start:     true
#...

Inside security.yml:

#...
    firewalls:
        login:
            pattern:  ^/admin/login$
            security: false
 
        secured_area:
            pattern:    ^/admin.*
            form_login:
                check_path: /admin/login_check
                login_path: /admin/login
                always_use_default_target_path: false
                default_target_path: /admin
            logout:
                path:   /admin/logout
                target: /admin/
            remember_me:
                key:      divine_office_hub_1234567
                lifetime: 31536000
                path: /
                domain: ~
 
        api_free:
           pattern: ^/v1.*
           form_login:
                check_path: /v1/user/login_check
                login_path: /v1/user/login
                always_use_default_target_path: true
                default_target_path: /v1/user/login_success
                username_parameter: username
                password_parameter: password
                remember_me: true
           logout:
                path:   /v1/user/logout
                target: /v1/user/logout_success
           remember_me:
                key:      divine_office_hub_76543211
                lifetime: 31536000
                path: /
                domain: ~
           anonymous: ~
#..

As you can see in security.yml I implemented remember_me on both firewalls, but one thing is missing here.
As you probably know, to make this work, client besides $_POST variables _username and _password when submitting login form, should add either check box or just include $_POST variable named: _remember_me inside POST request.

So, the case was next:
We have already published mobile app v1.0 to App Store and if we want remember_me functionality, we have to include in mobile version 1.1, but if users don’t update their apps it will not work for them.
Luckily, Symfony2 has also one more functionality for that:

always_remember_me: true

That way xou do not have to include β€œ_remember_me” POST parameter on client side, but Symfony2 will assume that parameter is present and set to true.

So, the final working security.yml looks like this:

#...
     firewalls:
 	#...
        api_free:
           pattern: ^/v1.*
           form_login:
                check_path: /v1/user/login_check
                login_path: /v1/user/login
                always_use_default_target_path: true
                default_target_path: /v1/user/login_success
                username_parameter: username
                password_parameter: password
                remember_me: true
           logout:
                path:   /v1/user/logout
                target: /v1/user/logout_success
           remember_me:
                key:      divine_office_hub_123456
                lifetime: 31536000
                always_remember_me: true
                remember_me_parameter: _remember_me
                path: /
                domain: ~
           anonymous: ~
#...

In the moment of log-in, server will besides cookie PHPSESSID also set cookie REMEMBER_ME
and user session even deleted on server (I tried) will be recreated with proper user token data.

Hope this helps to solve some of your problems too.
Cheers πŸ™‚


2 comments

  1. How do you check if user is logged? Will work

    $this->get('security.context')->isGranted('IS_AUTHENTICATED_FULLY')

    ?

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.