Skip to content

Instantly share code, notes, and snippets.

@JacobBennett
Last active June 4, 2023 05:50
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save JacobBennett/15558410de2a394373ac to your computer and use it in GitHub Desktop.
Save JacobBennett/15558410de2a394373ac to your computer and use it in GitHub Desktop.
Sharing Laravel Cookies across subdomains

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.

published: true
preview: Ever had a suite of applications hosted on a set of subdomains that all needed to be able to share a single cookie value? Here's how I accomplished it using Laravel's Cookie facade.
@ahsanatiq
Copy link

Thanks! That's the cool tip!

@JacobBennett
Copy link
Author

Glad you found it useful @ahsanatiq!

@navuitag
Copy link

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

@JacobBennett
Copy link
Author

@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.

@tuytoosh
Copy link

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.

@JacobBennett
Copy link
Author

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.

@acquayefrank
Copy link

How do I send "shared_cookie" during a redirect

@Mathius17
Copy link

Mathius17 commented Aug 29, 2016

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

@JacobBennett
Copy link
Author

@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')

@Mathius17
Copy link

@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!

@JacobBennett
Copy link
Author

Glad to help @Mathius17!

@JCarlosR
Copy link

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

@JCarlosR
Copy link

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!

@bogem25
Copy link

bogem25 commented Nov 29, 2018

Thanks a lot Jacob. It works ! Anyway, I still need to encrypt that cookie. Is it possible?

@dharmesh-infyom
Copy link

Thanks! JacobBennett for great tutorials.

@thainvnv
Copy link

thainvnv commented Apr 9, 2019

How about logout ? Can you tell me solution, thanks

@khan-aqib
Copy link

@JacobBennett thanks for posting such nice way. can we run same thing on subdomain1.domain.com and subdomain2.domain.com
as the domain.com is used by the website.

Regarding the session.php in both subdomains, do we have to update domain => '.domain.com'

@JacobBennett
Copy link
Author

Yes it should work fine since the root domain is the same.

Secondarily, sharing a cookie is not the same as having two different sites sharing sessions. To do that, you would need to make sure you have a non-local storage for your sessions in place, something like your database or redis.

@efraim14
Copy link

Hello, great information for sharing cookie.

I have one question, how do you remove the cookie? i need to Cookie::forget the shared_cookie but it's not working.

@depsimon
Copy link

depsimon commented Apr 3, 2020

Hey Jacob,

thanks for the gist it's helped me.

Have you noticed this doesn't work in Safari? (using v13)

It seems when we set the domain to ".example.com" or "example.com" when the app is actually on "app.example.com" it seems like it's blocked by the browser.
In my case I want to share between app.example.com & app2.example.com

It works in other browsers though...

@valh1996
Copy link

@depsimon Hello, have you found a solution to this please?

@depsimon
Copy link

Unfortunately not..

@JacobBennett
Copy link
Author

@depsimon and @valh1996, don't forget to add the cookie you are setting to the list of cookies that aren't encrypted by Laravel otherwise you would have to have a shared app key between the apps for it to work.

@depsimon
Copy link

Yep, tried that. It actually works with all other browsers. It's Safari-related because they have additional rules on shared cookies, at least when I tried back in April.

@ivanrojo07
Copy link

Thank you very much, it was very helpful. Greetings

@seoasia-co
Copy link

2023 Is this trip still working?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment