Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel sanctum csrf cookie every request?

I'm using Laravel sanctum (former Airlock) and have a question about it. I read in the docs:

To authenticate your SPA, your SPA's login page should first make a request to the /sanctum/csrf-cookie route to initialize CSRF protection for the application:

axios.get('/sanctum/csrf-cookie').then(response => {
// Login... }); 

Once CSRF protection has been initialized, you should make a POST request to the typical Laravel /login route. This /login route may be provided by the laravel/ui authentication scaffolding package.

Does this mean that for every request I make, I should first check if the cookie has already been set? Because let's say I have a user that registers. Before making the POST request to register a user I should first make a GET request to get the CSRF-Cookie from my backend and then make the POST request to register the user.

Now the user gets redirected to the login webpage and is asked to login. Does the frontend then first have to check if there's a CSRF-Cookie, and if there isn't should it first again make the GET request to get the cookie?

This last bit also confuses me, because when calling the register method a user doesn't actually get logged in so the user has to be redirect to the login page to log in with the credentials the user just filled in to register which for me seems like a bad user experience, right?

like image 224
Ezrab_ Avatar asked Mar 21 '20 11:03

Ezrab_


Video Answer


1 Answers

I know it's been a while since this question was asked but just for anyone searching out there, No. You don't have to call /sanctum/csrf-cookie with every request. Before you make a post | put | delete... request, you can check to see if the XSRF-TOKEN cookie is set. If it is not, make a call to the /sanctum/csrf-cookie route (or whatever you have configured it to be). After the request has completed, (the XSRF-TOKEN cookie would have been set by your browser automatically) you can now proceed with the initial request.

The best place to do this is in an interceptor (if your http library supports it). I'm going to assume you are using axios.

// Install with 'npm i js-cookie'. A library that helps you manage cookies 
// (or just build your own).
import Cookies from 'js-cookie';

// Create axios instance with base url and credentials support
export const axiosInstance = axios.create({
    baseURL: '/api',
    withCredentials: true,
});

// Request interceptor. Runs before your request reaches the server
const onRequest = (config) => {
    // If http method is `post | put | delete` and XSRF-TOKEN cookie is 
    // not present, call '/sanctum/csrf-cookie' to set CSRF token, then 
    // proceed with the initial response
    if ((
            config.method == 'post' || 
            config.method == 'put' || 
            config.method == 'delete',
            /* other methods you want to add here */
        ) &&
        !Cookies.get('XSRF-TOKEN')) {
        return setCSRFToken()
            .then(response => config);
    }
    return config;
}

// A function that calls '/api/csrf-cookie' to set the CSRF cookies. The 
// default is 'sanctum/csrf-cookie' but you can configure it to be anything.
const setCSRFToken = () => {
    return axiosInstance.get('/csrf-cookie'); // resolves to '/api/csrf-cookie'.
}

// attach your interceptor
axiosInstance.interceptors.request.use(onRequest, null);

export default axiosInstance;

The XSRF-TOKEN cookie comes with a time of expiry. After that time, the browser deletes it. So as long as you can find the cookie, it is safe to make a request without calling /sanctum/csrf-cookie or whatever you have configured it to be.

like image 111
Frank Avatar answered Sep 23 '22 09:09

Frank