Use Sanctum
LARAVEL BACKEND
- Install Sanctum via Composer
composer require laravel/sanctum
- Publish the Sanctum configuration and migration files
php artisan vendor:publish --provider="LaravelSanctumSanctumServiceProvider"
- Run your migrations - Sanctum will add a table to store API tokens
php artisan migrate
- Add Sanctum's middleware to your api middleware group in your
App/Http/Kernel.php
use LaravelSanctumHttpMiddlewareEnsureFrontendRequestsAreStateful;
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:60,1',
IlluminateRoutingMiddlewareSubstituteBindings::class,
],
- Configure which domains your SPA will be making requests from. From the docs:
You may configure these domains using the stateful configuration option in your sanctum configuration file. This configuration setting determines which domains will maintain "stateful" authentication using Laravel session cookies when making requests to your API.
So - Update your configsanctum.php
to include something like this:
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1')),
- Configure your
config/cors.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', '*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
- Configure your
config/session.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' => env('SESSION_DOMAIN', null),
- In your
.env
, add the following:
// Change .your-site.local to whatever domain you are using
// Please note the leading '.'
SESSION_DOMAIN=.your-site.local
SANCTUM_STATEFUL_DOMAINS=your-site.local:8000
CORS_ALLOWED_ORIGINS=http://app.your-site.local:8000
- Run a
php artisan config:clear
VUE FRONTEND
- In your front-end, create the following folder/file structure
@/src/services/api.js
api.js:
import axios from 'axios';
const apiClient = axios.create({
baseURL: process.env.VUE_APP_API_URL,
withCredentials: true,
});
export default apiClient;
In the root directory, place an .env file with the following in it:
VUE_APP_API_URL= 'http://api.your-site.local'
- To authenticate, your SPA should first make a request to the
/sanctum/csrf-cookie
. This sets the XSRF-TOKEN
cookie. This token needs to be sent on subsequent requests ( axios will handle this for you automatically ). Immediately after, you'll want to send a POST
request to your Laravel /login
route.
On your Vue front-end login component:
import Vue from 'vue'
import apiClient from '../services/api';
export default {
data() {
return {
email: null,
password: null,
loading: false,
};
},
methods: {
async login() {
this.loading = true; // can use this to triggle a :disabled on login button
this.errors = null;
try {
await apiClient.get('/sanctum/csrf-cookie');
await apiClient.post('/login', {
email: this.email,
password: this.password
});
// Do something amazing
} catch (error) {
this.errors = error.response && error.response.data.errors;
}
this.loading = false;
},
},