I am using Laravel as a backend API on a subdomain (api.example.com). My front end lies on a different subdomain (sub.example.com). I am using cookies as my session driver. I am also using laravel cors to handle the cross-domain requests (I'm not using CSRF for the moment) and it is working perfectly. However, I need a user to be able to log in on the front-end subdomain, have that log into the backend Laravel install through an AJAX request, and then the user remains logged in for all future requests from the front-end.
Currently when I do this, I can see that the authentication requests are going through and my authentication methods are running normally. However, it does not actually create any cookies. When I try to view the authenticated user on my backend I can see that no user is logged in. However, I created some test auth views on my backend and can login perfectly fine on the backend subdomain. It creates the session cookies and everything is normal. I modified my session domain config so that cookies will be shared across all subdomains, so I can even see those cookies on my frontend (when I login from the backend). Does anyone have experience with this? I'll post the relevant code below.
CustomAuthController
use Illuminate\Http\Request;
use Illuminate\Http\Response;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
use App\Models\User;
class CustomAuthController extends Controller
{
protected $user;
protected $auth;
public function __construct(Guard $auth, User $user)
{
$this->user = $user;
$this->auth = $auth;
}
public function getLogin()
{
return view('auth.login');
}
public function postLogin(Request $request)
{
if ($this->auth->attempt($request->only('email', 'password')))
{
return (new Response('logged in',200));
}
return redirect('/login')->withErrors([
'email' => 'The credentials you entered did not match our records. Try again?',
]);
}
public function getLogout()
{
$this->auth->logout();
return (new Response('logged out',200));
}
}
config/session.php
return [
//other session config
'domain' => '.example.com',
]
config/cors.php (laravel-cors config, currently allowing all domains, will change after testing)
return [
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedHeaders' => ['*'],
'allowedMethods' => ['GET', 'POST', 'PUT', 'DELETE'],
'exposedHeaders' => [],
'maxAge' => 0,
'hosts' => [],
];
AJAX request on the front-end (sub.example.com)
$.ajax({
type: 'POST',
url: 'http://api.subdomain.com/auth/login',
data: {
'email': $('#email').val(),
'password': $('#password').val()
},
success: function(response){
console.log(response);
}
});
Again, if I use this AJAX request from my front-end, I can see that it makes a successful request to my CustomAuthController. The AJAX call returns a 200 status response with the expected "logged in" text returned. Just for some reason I am having no cookie set and therefore the authentication is not persistent. I can see that on my backend. But if I log in on my backend install, those cookies are created and available to my front-end. Any ideas how to make this work?
I figured out what was wrong and wanted to post in case it will help anyone else.
My issue was that I needed to set the credentials in order for the cross domain cookies to work. So I had to change my laravel-cors config to:
return [
'supportsCredentials' => true,
'allowedOrigins' => ['*'],
'allowedHeaders' => ['*'],
'allowedMethods' => ['GET', 'POST', 'PUT', 'DELETE'],
'exposedHeaders' => [],
'maxAge' => 0,
'hosts' => [],
];
And then in my AJAX request, I had to add the appropriate parameter:
$.ajax({
type: 'POST',
url: 'http://api.subdomain.com/auth/login',
xhrFields: {
withCredentials: true
},
data: {
'email': $('#email').val(),
'password': $('#password').val()
},
success: function(response){
console.log(response);
}
});
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community