Laravel sanctum csrf cookie каждый запрос?
Я использую Laravel sanctum (бывший Airlock) и у меня есть вопрос по этому поводу. Я читал в документах:
Для аутентификации вашего SPA страница входа вашего SPA должна сначала сделать запрос к маршруту /sanctum/csrf-cookie для инициализации защиты CSRF для приложения:
axios.get('/sanctum/csrf-cookie').then(response => {
// Login... });
После инициализации защиты CSRF вы должны сделать POST-запрос по типичному маршруту Laravel / входа в систему. Этот маршрут /login может быть предоставлен пакетом шаблонов аутентификации laravel/ui.
Означает ли это, что при каждом моем запросе я должен сначала проверять, был ли уже установлен файл cookie? Допустим, у меня есть пользователь, который регистрируется. Перед отправкой запроса POST для регистрации пользователя я должен сначала сделать запрос GET, чтобы получить CSRF-Cookie из моего бэкэнда, а затем сделать запрос POST для регистрации пользователя.
Теперь пользователя перенаправляют на веб-страницу входа в систему и просят войти в систему. Должен ли интерфейс сначала проверить, есть ли CSRF-Cookie, и, если его нет, должен ли он сначала снова сделать запрос GET, чтобы получить cookie?
Этот последний бит также меня смущает, потому что при вызове метода регистрации пользователь фактически не входит в систему, поэтому пользователь должен быть перенаправлен на страницу входа, чтобы войти в систему с учетными данными, которые пользователь только что заполнил для регистрации, что для меня кажется как плохой пользовательский опыт, верно?
3 ответа
Когда вы получите токен csrf, в следующем запросе laravel обновит токен автоматически, поэтому вам не нужно фокусироваться на этом после axios.get('/sanctum/csrf-cookie')
.
Я знаю, что прошло много времени с тех пор, как этот вопрос был задан, но просто для тех, кто ищет там: Нет. Вам не нужно звонить с каждым запросом. Прежде чем сделать
post | put | delete...
запрос, вы можете проверить, установлен ли файл cookie. Если это не так, сделайте вызов маршрута (или того, что вы настроили). После выполнения запроса (т.
XSRF-TOKEN
cookie был бы установлен вашим браузером автоматически), теперь вы можете выполнить первоначальный запрос.
Лучше всего это сделать в перехватчике (если ваша 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;
Файл cookie XSRF-TOKEN имеет срок действия. По истечении этого времени браузер удаляет его. Поэтому, пока вы можете найти файл cookie, можно безопасно сделать запрос, не вызывая
/sanctum/csrf-cookie
или то, что вы настроили, чтобы это было.
Как только вы ударите axios.get('/sanctum/csrf-cookie')
API, после этого вам не нужно нажимать его снова и снова для каждого запроса, потому что это/sanctum/csrf-cookie
сохранит токен XSRF в браузере, и Axios отправит его с запросом.
Подробнее об этом вы можете узнать из этого видео: https://www.youtube.com/watch?v=8Uwn5M6WTe0