- Automatic Token Auth, after Log-In via Web Auth.
- No Tokens Stored in LocalStorage.
- No Tokens Stored in Database.
- No OAuth Needed.
Credits: @CodeMonkey
composer require laravel/passport
artisan passport:install
artisan migrate
config/auth.php
<?php
return [
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport',
'provider' => 'users',
'hash' => false,
],
],
];
<?php
Auth::routes();
Route::view('{slug?}', 'layouts.spa')
->where('slug', '^(?!telescope|nova).*?$')
->name('spa');
<?php
Route::group([
'prefix' => 'account',
'middleware' => 'auth:api',
], function(){
Route::get('/', function(){
return response(['user' => request()->user()]);
});
});
We'll return our user for json requests.
<?php
if (Auth::guard($guard)->check()) {
if($request->wantsJson()){
return response()->json(['user' => $request->user()]);
}
return redirect('/');
}
This is where the magic happens, everytime we visit a web route, we get a new token when authorized. So, once we login, we're ready to use authenticated API routes. Laravel will inject a cookie into web route responses that will be automatically used by Axios during future api requests. We use an HttpOnly cookie to secure our token. No need to store anything manually.
<?php
$middlewareGroups = [
'web' => [
//...
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
//...
],
];
If we want our login and logout functionality to be seamless we need to do a few things to give Axios some help.
Override the trait methods to return your user and the csrf_token. (App\Http\Controllers\Auth\LoginController.php)
<?php
/**
* The user has been authenticated.
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(Request $request, $user)
{
return response()->json([
'user' => $user,
'csrf_token' => $request->session()->token()
]);
}
/**
* The user has logged out of the application.
* @param \Illuminate\Http\Request $request
* @return mixed
*/
protected function loggedOut(Request $request)
{
$request->session()->regenerate();
return response()->json([
'csrf_token' => $request->session()->token()
]);
}
client.interceptors.response.use((response) => {
if(response.data && response.data.csrf_token){
client.defaults.headers.common['X-CSRF-TOKEN'] = csrf_token
}
return Promise.resolve(response)
})