Luuk Van Dongen
Luuk Van Dongen

Reputation: 2501

Laravel: share session data over multiple domains

I'm building a multi-domain/multi-store ecommerce application in Laravel and would like to keep the user logged in when he or she changes from store to store.

But for as far as I know Laravel's Auth service saves the logged in user in the session and the sessions can't be accessed by other domains.

Is there a way (maybe a package) to achieve this, without leaving my application prone to possible security problems?

Thanks in advance!

Upvotes: 15

Views: 33797

Answers (7)

SaidbakR
SaidbakR

Reputation: 13552

Based on this answer of Chirag Prajapati. Yo could use $_SERVER['HTTP_HOST'] in the env entry:

From /config/session.php

'domain' => env('SESSION_DOMAIN', $_SERVER['HTTP_HOST']),

Then from the app root: php artisan config:clear and don't keep attention to warning messages, just be sure at the end you have gotten Configuration cache cleared! By this way your app session will work fine on whatever domain you have.

Upvotes: 0

sergio0983
sergio0983

Reputation: 1288

I know this is not exactly what was asked for, but, for development and testing purposes, I did this:

In config/session.php, try changing this line

'path' => '/',

Into this

'path' => '/;SameSite=None; secure',

allowed me to authenticate from different domains.

Now, you should be able to write a simple middleware to prevent unwanted hosts. Something like this.

namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Closure;

class TrustedHosts{
    public function handle($request, Closure $next){
        //$host = $request->getHost();
        $host = $request->headers->get('origin');
        $enviroment = env('APP_ENV');

        if ( $enviroment == 'development' ) {
            $trustedHosts = array('localhost', 'dev.mydomain.com');
        }
        else {
            $trustedHosts = array('anotherdomain.com', 'mydomain.com');
        }
        
        $isHostTrusted = in_array($host, $trustedHosts);
        
        if ( !$isHostTrusted ) return response("I'm a teapot", 418); //Or any other code and message that you prefer.
        return $next($request);
    }
}

And group it in the middleware group that includes the session stuff.

Upvotes: 1

Chirag Prajapati
Chirag Prajapati

Reputation: 539

If you want to share the session between multiple subdomains in that case you have to set the domain name config/session.php has set the domain name.

Example: if you have new.example.com and test.example.com so you have to set the domain name as example.com

'domain'     => env('SESSION_DOMAIN_URL','.example.com')

Solutions there worked for me, specifically setting the domain and then clearing my browser cookies & cache.

Upvotes: 5

mateos
mateos

Reputation: 1563

  1. On domain A create an image like so <img src="https://DOMAINB.com/setcookie?id={{ Session::getId() }}" style="display:none;" />

  2. On Domain B create a Route like so:

.

Route::get('setcookie', function(){
  Session::setId($_GET['id']);
  Session::start();
  return 'Cookie created';
});`
  1. Done, Now you should be able to get your user by $user = Auth::User;

Upvotes: 4

Sharath TS
Sharath TS

Reputation: 106

  1. Capture the session id Session::getId() in Domain A
  2. send the captured session id via HTTP POST to Domain B
  3. Access the sent session id in domain B $sessionid_from_domainA = $_POST['session_from_A']
  4. Set session in domain B Session::setId($sessionid_from_domainA)
  5. Start Session in domain B Session::start()

Upvotes: 9

DfKimera
DfKimera

Reputation: 2146

You can manually set which domain the session cookies will be registered, and thus have them persist across different sites. Just edit config/session.php, in the following section:

<?php
/*
    |--------------------------------------------------------------------------
    | Session Cookie Domain
    |--------------------------------------------------------------------------
    |
    | Here you may change the domain of the cookie used to identify a session
    | in your application. This will determine which domains the cookie is
    | available to in your application. A sensible default has been set.
    |
    */

    'domain' => null,
?>

You're still restricted to a single top-level domain, though. So you can have store1.shops.com and store2.shops.com sharing sessions, but not myshop.com and shopsmart.com.

If you need something in this format, you'll probably fare better by creating an authentication service, and using access tokens to validate the credentials. You might also give a look at services like OneLogin.

Upvotes: 1

CatZ
CatZ

Reputation: 43

I am working on something like that too a single sign-on system, still working to find a solution, but here is a start http://laravel.io/forum/03-14-2014-multiple-domains-how-to-share-login

On laravel you can change the /app/config/session.php driver to cookie


Edit:

This is what I have done.

You can share cookie accross domains using pixel images. For example when you login on domain1.com you want to create a cookie on domain2.com, right after login on domain1.com you need to have something like this

<img src="http://www.domain2.com/create-cookie?param=hash">

on domain2.com the route above:

  1. will check first if a user is logged in
    1. if its not logged in will read the hash (for example email address), check if there is a user with that email, and login it there, also set a cookie

Upvotes: 1

Related Questions