Sharing Laravel Cookies across subdomains

By JacobBennett

I recently ran into a problem where I had a suite of applications hosted on a set of subdomains that all needed to be able to share a single cookie. Any cookies other than the shared cookie needed to stay specific to their subdomain, but this one shared cookie needed to be accessible to any of them. I also wanted to accomplish this using Laravel's Cookie facade.

The Problem

To accomplish this, there were two issues to solve.

  1. All cookies created by the Laravel framework are encrypted by default. (link)
  2. I needed to figure out how to set a domain on the shared cookie that was different than the domain it was being set from.

Setting Non-Encrypted Cookies

In Laravel 5.1, a feature was added which allows you to add a list of cookie names that should not be encrypted to the EncryptCookies Middleware under the $except array. Check out the docs for information on how to accomplish this.

In my EncryptCookies Middleware, I changed the $except array to include my cookie name.

  protected $except = [
        'shared_cookie'
    ];

Setting a Custom Domain

After reading an article discussing the issue of sharing cookies across subdomains, I realized that I needed to create the shared cookie with a domain that was different from the default value. The default domain value for all cookies is the domain your site is located at. If your site was subdomain.example.com all cookies by default would be set for that domain. In order to share a cookie across subdomains however, a cookie needs to be created with a domain of .example.com. Notice the leading . in the domain of the cookie. This is important. By setting the domain as such, any subdomain will be able to access this cookie as it's own.

There is a domain setting in config/session.php that will allow you to change the default domain that cookies are set from, but I wanted to maintain this default, and only override the behavior for the one shared cookie. To accomplish this, I had to dig into the CookieJar class of Laravel and see exactly how these cookies were being created.

Come to find out, the make method of the CookieJar class accepts a list of arguments that includes a spot for a domain. The default is used if a null value is passed in for the domain, but we can easily pass in our own domain.

  $num_of_minutes_until_expire = 60 * 24 * 7; // one week
  Cookie::queue('shared_cookie', 'my_shared_value', $num_of_minutes_until_expire, null, '.example.com');

This will send a cookie along with our next response which will not be encrypted (thanks to EncryptCookies), and will have a domain of .example.com which will allow us to access it from any subdomains.

Created 2 years ago | Updated 1 month ago

Comments (13)

Thanks! That's the cool tip!

Glad you found it useful @ahsanatiq!

Thanks. But, what about the laravel 4.1.x ?

@Vilisag the non-encrypted cookies aren't supported in version 4.1. Not setting them using the Cookie facade anyway. You could set a cookie using plain PHP and follow the same rules as stated above, placing a period in front of the domain you are hoping to share it across.

Hi , I am logged in in example.com... but when I navigate to sub.example.com I have not logged in... can this tutorial help me about that? if not, give me a solution please.

Yes it should be able to. If you go to session.php and look at the path key under the Session Cookie Path, and you set that to .example.com that should enable it to work across subdomains.

How do I send "shared_cookie" during a redirect

Hi @JacobBennett I'm doing the exact same thing as you, leaving the domain option inside config/session.php alone and setting the .domain.com inside the Cookie::queue method. My question is, how would I access that cookie from another subdomain (that is using Laravel)? I've tried with $request->cookie('name') but it doesn't work, I can only retrieve cookies from sub.domain.com, not .domain.com

@Mathius17 did you make sure that you are not encrypting the contents of the cookie? If so, then you should be able to access it just like any other cookie. Cookie::get('cookie_key')

@JacobBennett I got it to work, the trick was to put the shared cookie inside the $except array in EncryptCookies.php in both projects. I was only doing it in the project that created the cookie. Thanks for the help!

Glad to help @Mathius17!

Thank you for the tutorial Jacob.
Please help me. I am trying to share the cookies created by the login.
I have changed the value of the key path in config/sesion.php for .localhost.com. I have also changed the value of the key domain for the same.
But when I login from series.localhost.com, the session is only available for localhost.com and not for series.localhost.com (from the subdomain I am using a request to localhost.com/sessions).

Sorry, it is working now. I had to clear the cookies in my browser.
So I will change the question =)
Is there any difference between path and domain?
Thank you!