简体   繁体   中英

symfony 2.8 - session lost after success login redirect ( there is 2 session id in cookie )

I'm using symfony 2.8 and have a problem with authentication sometimes. the problem is session lost after success login redirect . after hours to figure out I'v found something : there is 2 session id in cookie

Header  Value

accept-encoding gzip, deflate, sdch
accept-language en-US,en;q=0.8
cache-control   max-age=0
connection  keep-alive
cookie  PHPSESSID=lme2ce9uk749eklbpnveeuir93; PHPSESSID=601fefa02332bbd4bea06a9603a8b7d6

I think , it's cause to faild redirect after login

Could you help me !?? :(

在此处输入图片说明


Edited

I forgot to say this application work fine with IP this problem appears when client use domain name

it's my security

security:
    encoders:
        Proshut\UserBundle\Entity\User:
            algorithm: bcrypt 
    access_decision_manager:
        strategy:  unanimous
    providers:
        office:
          entity: { class: ProshutUserBundle:User }
    firewalls:
        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false
        security:
            pattern:  ^/(login|signup|openid|reset)$
            security: false
        ajax:
            pattern:  ^/(report|account)/ajax$
            security: false
        webservice:
            pattern:  ^/webservice(/[a-zA-Z]*)?$
            security: false
        captcha:
            pattern:  ^/generate/gcb_captcha$
            security: false
        office_area:
            pattern: ^/
            simple_form:
                provider: office
                authenticator: user.listener.authenticator
                check_path: /login_check
                login_path: /login
                default_target_path: /dashboard
                use_referer: true
                username_parameter: form[_username]
                password_parameter: form[_password]
                failure_handler: user.listener.authentication.handler
                success_handler: user.listener.authentication.handler
            logout:
                path:   /logout
                target: /login
            http_basic: ~

    access_control:
        - { path: ^/, roles: IS_AUTHENTICATED_ANONYMOUSLY } 

Your security config looks ok, but you store your session in the database. Problem with sql session is race condition. Your handler return session before new value is written to session table. When you use PHP-FPM, symfony does the dispatching of the kernel.terminate event after sending the response to improve the response time, and the session is written in this event.

An workaround for this problem is to force the session save before the response is sent to the client, and to do this you can create a listener for the response event in symfony, something like this:

    class ResponseListener
    {
        public function onKernelResponse(FilterResponseEvent $event)
        {
            if ($event->isMasterRequest() && $event->getRequest()->get('_route') == 'security_check_route') {

                $event->getRequest()->getSession()->save();

                return;
            }
        }    
    }

In the above example I added the second part of the if statemant, to only force session write on login. If you keep that part, replace security_check_route with the name of your security check route. If you want to force session write before return on every route, then remove that part of the condition.

Below is an example of configuration for the listener

<service id="response_listener" class="PathTo\ResponseListener">
    <tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
</service>

Hope this helps,

Alexandru Cosoi

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM