5

我正在使用 Laravel sanctum(前 Airlock)并且对此有疑问。我在文档中读到:

要验证您的 SPA,您的 SPA 登录页面应首先向 /sanctum/csrf-cookie 路由发出请求,以初始化应用程序的 CSRF 保护:

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

一旦 CSRF 保护被初始化,你应该向典型的 Laravel /login 路由发出 POST 请求。此 /login 路由可能由 laravel/ui 身份验证脚手架包提供。

这是否意味着对于我提出的每个请求,我都应该首先检查 cookie 是否已经设置?因为假设我有一个注册用户。在发出 POST 请求来注册用户之前,我应该首先发出 GET 请求以从我的后端获取 CSRF-Cookie,然后发出 POST 请求来注册用户。

现在用户被重定向到登录网页并被要求登录。那么前端是否首先必须检查是否有 CSRF-Cookie,如果没有,是否应该首先再次发出 GET 请求来获取 cookie?

最后一点也让我感到困惑,因为当调用 register 方法时,用户实际上并没有登录,所以用户必须被重定向到登录页面才能使用用户刚刚填写的凭据登录,这对我来说似乎就像糟糕的用户体验一样,对吧?

4

3 回答 3

3

当你得到 csrf 令牌时,在下面的请求中,laravel 会自动更新令牌,所以你不需要在之后关注这个 axios.get('/sanctum/csrf-cookie')

于 2020-03-21T13:12:55.480 回答
3

一旦你点击了axios.get('/sanctum/csrf-cookie')API,之后你就不必为每个请求一次又一次地点击它,因为这/sanctum/csrf-cookie会将 XSRF 令牌保存在浏览器上,而 Axios 会将它与请求一起发送。

您可以在此视频中详细了解它:https ://www.youtube.com/watch?v=8Uwn5M6WTe0

于 2020-04-09T09:43:14.743 回答
3

我知道这个问题被问到已经有一段时间了,但对于任何在那里搜索的人来说,不。你不必/sanctum/csrf-cookie每次请求都打电话。在发出post | put | delete...请求之前,您可以检查是否XSRF-TOKEN设置了 cookie。如果不是,请调用/sanctum/csrf-cookie路由(或任何您配置的路由)。请求完成后(XSRF-TOKENcookie 将由您的浏览器自动设置)您现在可以继续执行初始请求。

执行此操作的最佳位置是在拦截器中(如果您的 http 库支持它)。我将假设您正在使用 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;

XSRF-TOKEN cookie 带有到期时间。在那之后,浏览器将其删除。因此,只要您能找到 cookie,就可以安全地发出请求,而无需调用/sanctum/csrf-cookie或任何您配置的请求。

于 2021-12-04T21:15:04.717 回答