skip to Main Content

symfoniers! I have the unknown problem, I can’t find what I did wrong.
We have working site on symfony 2.3 with sylius 0.11 version, nginx 1.10, varnish 4.1, php5.5.

So when we try to set up configuration ready new config of varnish everything were good. But then we were taking disappointing comment like “I login to my account but got to another user!”. We turn off our varnish and rollback nginx config. But problem was still chased us.

We decided to delete all sessions in cache because we thought varnish somehow broke session mechanism. It looks like it helps us. But we don’t know for sure.

Then we correct the varnish config and try again. The same problem.

In this connection, I have two question:

How to decide problem of logging to another user?
Where is the root of this problem? Can somebody suggest any solutions?

Our varnish config:

vcl_recv {
    if (req.method == "POST") {
        return (pass);
    }

    if (req.url ~ "/administration/?.*" ||
        req.url ~ "/app_dev.php/?.*" ||
        req.url ~ "/account/?.*" ||
        req.url ~ "/cart/?.*" ||
        req.url ~ "/currency/?.*" ||
        req.url ~ "/login_check/?.*" ||
        req.url ~ "/login/?.*" 
        req.url ~ "/logout/?.*" 

     ) {
          return (pass);
     } 

    if (req.http.Cookie) {
        set req.http.Cookie = ";" + req.http.Cookie;
        set req.http.Cookie = regsuball(req.http.Cookie, "; +", ";");
        set req.http.Cookie = regsuball(req.http.Cookie, ";(ProductsViewMode|PHPSESSID|currency|APP_REMEMBER_ME|recentViews|mobile)=", "; 1=");
        set req.http.Cookie = regsuball(req.http.Cookie, ";[^ ][^;]*", "");
        set req.http.Cookie = regsuball(req.http.Cookie, "^[; ]+|[; ]+$", "");

        if (req.http.Cookie == "") {
            unset req.http.Cookie;
        }
    }

    #all pictures cache by 15 minutes
    if (req.url ~ "^.*.(png|jp[e]?g|gif|swf|css|js|svg)?(?v=.*)?$") {
        unset req.http.Cookie;
#        set req.ttl = 900s;
        return (hash);
    }

    #clear all cache content

    if (req.method == "PURGE") {
        if (!client.ip ~ invalidators) {
            return (synth(405, "Not allowed"));
        }
        return (purge);
    }
return (hash);
}

sub vcl_hash {

    #unset req.http.Cookie;

    set req.http.X-Have-To-Hash = ";" + req.http.Cookie;
    set req.http.X-Have-To-Hash = regsuball(req.http.X-Have-To-Hash, "; +", ";");
    set req.http.X-Have-To-Hash = regsuball(req.http.X-Have-To-Hash, ";(ProductsViewMode|currency|recentViews|mobile)=", "; 1=");
    set req.http.X-Have-To-Hash = regsuball(req.http.X-Have-To-Hash, ";[^ ][^;]*", "");
    set req.http.X-Have-To-Hash = regsuball(req.http.X-Have-To-Hash, "^[; ]+|[; ]+$", "");

    if (req.http.Cookie ~ "APP_REMEMBER_ME") {
        set req.http.X-Have-User = "true";
    } else {
        set req.http.X-Have-User = "false";
    }

    hash_data(req.url);
    hash_data(req.http.host);
    hash_data(req.http.X-Have-To-Hash);
    hash_data(req.http.X-Have-User);

    return (lookup);

}


sub vcl_backend_response {

    #for ban some objects
    set beresp.http.X-Url = bereq.url;
    set beresp.http.X-Host = bereq.http.host;

    if (beresp.http.Cache-Control ~ "private" ||
        beresp.http.Cache-Control ~ "no-cache" ||
        beresp.http.Cache-Control ~ "no-store"
    ) {
        set beresp.ttl = 1h;
#        set beresp.uncacheable = true;
        unset beresp.http.Cache-Control;
    }

    if (beresp.http.X-Url ~ "^.*.(png|jp[e]?g|gif|swf|css|js|svg)?(?v=.*)?$") {
        set beresp.ttl = 24h;
    }

    if (beresp.status == 502 || beresp.status == 404 || beresp.http.X-Cache-Debug) {
        set beresp.ttl = 0s;
    }

return (deliver);
}

Our security config:

# This file is part of the Sylius package.
# (c) Paweł Jędrzejewski

security:
    providers:
        fos_userbundle:
            id: fos_user.user_provider.username
    encoders:
        FOSUserBundleModelUserInterface: sha512
    firewalls:
        administration:
            switch_user: true
            context:     user
            pattern:     /administration/.*
            form_login:
                provider:     fos_userbundle
                login_path:   /administration/login
                check_path:   /administration/login-check
                failure_path: /administration/login
                default_target_path: /administration/dashboard
                use_forward:  false
                use_referer:  true
            logout:
                path:   /administration/logout
                target: /administration/login
            anonymous: true

        main:
            switch_user: { role: ROLE_SYLIUS_ADMIN }
            context:     user
            pattern:     /.*
            form_login:
                provider: fos_userbundle
                login_path: /login
                check_path: /login_check
                success_handler: authentication_handler
                failure_handler: authentication_handler
                failure_path: /login
                default_target_path: /
                use_forward:  false
                use_referer: true
            remember_me:
                key: %sylius.secret%
                name: APP_REMEMBER_ME
                lifetime: 31536000
                always_remember_me: true
                remember_me_parameter: _remember_me
            oauth:
                resource_owners:
                    facebook: "/login/check-facebook"
                    vk: "/login/check-vkontakte"
                    twitter: "/login/check-twitter"
                    google_plus: "/login/check-google"
                login_path:   /login
                failure_path: /login
                default_target_path: /account/profile
                oauth_user_provider:
                    service: ostrov_user_provider
            logout: true
            anonymous: true

        dev:
            pattern:  ^/(_(profiler|wdt)|css|images|js)/
            security: false

    access_control:
        - { path: ^/login.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/connect.*, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: /api/checkauth.*, role: IS_AUTHENTICATED_ANONYMOUSLY }

        - { path: ^/administration/login, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/administration/login-check, role: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: "/administration.*", role: ROLE_SYLIUS_ADMIN }
        - { path: /api.*, role: ROLE_API }

        - { path: "/account.*", role: ROLE_USER }
        - { path: "/account.*", role: ROLE_MANAGER }

        - { path: "/_partial.*", ip: 127.0.0.1 }

    role_hierarchy:
        ROLE_MANAGER:     [ROLE_USER]

And one more question: how session_start() give a session id? What mechanism of getting to user the PHPSESSID? Does it check the existed sess_id and does it reset sess if nginx reload or if server become to another server?

2

Answers


  1. Chosen as BEST ANSWER

    So, what the problem was:

    We cached all the pages, so someone pages containts Set-Cookie header. So after we correct this lines

    if (beresp.status == 502 || beresp.status == 404 || beresp.http.X-Cache-Debug) {
        set beresp.ttl = 0s;
    }
    

    to this

    if (beresp.status > 400 || 
        beresp.http.X-Cache-Debug ||
        beresp.http.Set-Cookie ~ "PHPSESSID"
    ) {
           set beresp.ttl = 0s;
      }
    

    everything became all right.

    Hope this helps to someone. Good luck!


  2. With your varnish vcl you mess with cookies :

    1. When varnish receives the request it removes some cookies using regex.
    2. Then when you hash the request to create the cache key you try to use the same cookies you just removed.

    Usually the first step is done to remove front end cookies that do not change the backend behaviour and thus are useless in the cache key.

    This is done because varnish basically does not cache requests with cookies (this can be seen in the builtin.vcl).

    I think you should remove your cookie handling lines in vcl_hash and in vcl_recv. This should solve your problem but any request received with a cookie will end up in a PASS (not cached). If you really want to cache some requests even if cookies, then you should do some handling :
    . In vcl recv unset cookie if it is of no value, returning hash if it changes the response.
    . In vcl_hash add the cookies that are of value to the hash parameters.

    Moreover, In your example, I think your regexp ;[^ ][^;]* is too aggressive and delete every Cookie.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search