For those who are unfamiliar with Laravel, it is a very popular monolithic PHP web framework similar to others like Ruby on Rails. It is known for its ease of use, rapid development and making PHP development far more enjoyable haha!
Sanctum is an official Laravel package that is designed to provides a featherweight authentication system for SPAs and simple APIs. Sanctum is by far the easiest way to add authentication to a Laravel application.
Sanctum offers an API token approach designed for authenticating APIs and mobile applications, which is fairly easy to setup. On the other hand the cookie bases SPA authentication method can be quite confusing to configure. Which is unfortunate as this is the method most people will be using.
So here I am going to show you how to configure the Sanctum SPA Authentication in Laravel 11.x and test it with Postman. I will also include an Axios configuration to easily authenticate from your SPA also!
NOTE: The SPA authentication method only works if the request is coming from the same domain, but can come from different subdomains. For example website.com
can authenticate to api.website.com
.
Follow along with the Sanctum documentation here.
Installation & Configuration of Sanctum
By default Laravel does not include authentication, but provides artisan commands to install and scaffold Sanctum. It will generate a few files you will need, like a database migration and a config file specifically for Sanctum.
bash
php artisan install:api
Configuring Your First-Party Domains
In your .env
file you will want to add the domain which you will be accepting requests from. This will be used to verify the Referer
header, and if not found the Origin
header.
env
SANCTUM_STATEFUL_DOMAINS=website.com
- or -
SANCTUM_STATEFUL_DOMAINS=spa.website.com
Sanctum Middleware
Inside bootstrap/app.php
you want to add the stateful API middleware to the entire application, this can be done with the following. Without this middleware any route protected by the auth:sanctum
middleware will fail.
PHP
->withMiddleware(function (Middleware $middleware) {
//
$middleware->statefulApi();
})
CORS and Cookies
For almost any application you will want CORS enabled, Sanctum requires it to function properly. You can easily scaffold its configuration with the following:
bash
php artisan config:publish cors
This will generate the config/cors.php
file. In this file you will simply need to set the supports_credentials
to true
. This will prevent the cookies from being blocked by CORS.
Lastly for this section you will to edit the SESSION_DOMAIN
in your .env
file. You will want to change it to the domain of your SPA or you can prefix it with a .
to make it accept all subdomains.
For example .website.com
will allow any subdomain.
Logging In
So now we have everything in place to verify out tokens, but we need to create the login route which will verify our email and password and associate that with our session.
You can easily just add the following to your routes/web.php
PHP
use Illuminate\Support\Facades\Auth;
Route::post('/login', function () {
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return Response([
'message' => 'Successful login!'
], 200);
}
return Response([
'message' => 'Mismatch email and password!'
], 401);
});
You can also follow the example provided by Laravel however it does not return JSON like above, but a redirect response.
Configure Postman Collection
Before we configure Postman I want to briefly discuss the operations required for logging in.
First Sanctum needs us to hit the /sanctum/csrf-cookie
endpoint with a GET
request. This will return a 204 request meaning it was successful but has no content, it only contains our session cookies.
Then we can make a POST
request to our newly created /login
route with an an email
and password
in the body to authenticate and associate the authenticated user with the session matching the issued token in our previous step.
Now we are fully authenticated and can use any sanctum protected route by passing the cookie along with the header X-XSRF-TOKEN
containing the parsed value of the cookie in the request. This can be tested by making a request to the /api/user
route that is included by default.
Don't worry Postman and Axios can easily manage the cookies and headers for us!
The postman collection
You can download this Laravel 11.x Sanctum SPA Collection to follow along.
The key to the postman collection lies in our collection Pre-request script:
JavaScript
const jar = pm.cookies.jar();
jar.get("http://localhost:5174", "XSRF-TOKEN", (err, cookie) => {
pm.request.addHeader({
key: "X-XSRF-TOKEN",
value: cookie
});
pm.request.addHeader({
key: "Origin",
value: "http://localhost:5174"
});
pm.request.addHeader({
key: "Referer",
value: "http://localhost:5174"
});
});
This script will run before every request, parsing the cookies found for the given origin and adding them to the X-XSRF-TOKEN
header. It also sets both the Referer
and Origin
header which sanctum requires.
You may notice that I have set the Referer
and Origin
header to localhost:5174
this is simply because that is a common port for SPA applications built with Vite!
NOTE: If this fails at any point it is probably because Postman requires you to give access to the cookies that belong to the origin. You can do it with the following process:
Axios configuration
Axios is a promise based HTTP client for JavaScript giving you a really easy way to work with HTTP requests. In our case it offers configuration points that make working with Sanctum extremely easy.
JavaScript
import axios from 'axios';
let axiosInstance = axios.create({
baseURL: 'http://localhost',
timeout: 1000,
headers: {
Accept: 'application/json'
},
withCredentials: true,
withXSRFToken: true,
xsrfCookieName: "XSRF-TOKEN",
xsrfHeaderName: "X-XSRF-TOKEN",
});
export default axiosInstance;
By examining the above configuration, if you are familiar with Axios, you will see that its a pretty simple Axios configuration except for 4 configurations:
- withCredentials
- withXSRFToken
- xsrfCookieName
- xsrfHeaderName
Lets first discuss the withCredentials
. This option tells Axios to attach cookies found in the browser batching the origin to the request.
Next is withXSRFToken
. This option tells Axios to set the XSRF header only for requests of the same origin.
Finally xsrfCookieName
and xsrfHeaderName
tell Axios which cookie to parse for the header, and the name of the header to attach. Both options default to the values given in the above configuration which Sanctum expects.
Now any requests made with this Axios instance will be compatible with Laravel Sanctum SPA authentication!
Top comments (0)