Laravel sanctum csrf cookie every request?

14,344

Solution 1

When you get the csrf token, in the following request, laravel will update the token automatic, so you dont need focus this after axios.get('/sanctum/csrf-cookie').

Solution 2

Once you hit axios.get('/sanctum/csrf-cookie') API, after that you don't have to hit it again and again for every request, Because this/sanctum/csrf-cookie will save the XSRF token on browser and Axios will send it with the request.

You can learn about it in detail in this video: https://www.youtube.com/watch?v=8Uwn5M6WTe0

Solution 3

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.

Share:
14,344
Ezrab_
Author by

Ezrab_

Updated on June 23, 2022

Comments

  • Ezrab_
    Ezrab_ almost 2 years

    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?

  • Ezrab_
    Ezrab_ about 4 years
    So basically I should just make the request one when registering and after that Laravel does the magic each request itself?
  • leonzai
    leonzai about 4 years
    Check this, bilibili.com/video/av96088617. There is a sample in it.