Используйте Sanctum
LARAVEL BACKEND
- Установите Sanctum через Composer
composer require laravel/sanctum
Publi sh файлы конфигурации и миграции Sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Запустите миграцию - Sanctum добавит таблицу для хранения токенов API
php artisan migrate
Добавьте промежуточное ПО Sanctum в вашу группу промежуточного ПО
api в
App/Http/Kernel.php
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;
'api' => [
EnsureFrontendRequestsAreStateful::class,
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
Настройте, с каких доменов ваш SPA будет делать запросы. Из документов:
Вы можете настроить эти домены, используя параметр конфигурации с отслеживанием состояния в файле конфигурации sanctum. Этот параметр конфигурации определяет, какие домены будут поддерживать аутентификацию с отслеживанием состояния с использованием Laravel файлов cookie сеанса при выполнении запросов к вашему API.
Итак - обновите свой config\sanctum.php
, включив что-то вроде этого:
/*
|--------------------------------------------------------------------------
| Stateful Domains
|--------------------------------------------------------------------------
|
| Requests from the following domains / hosts will receive stateful API
| authentication cookies. Typically, these should include your local
| and production domains which access your API via a frontend SPA.
|
*/
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', 'localhost,localhost:8000,127.0.0.1,127.0.0.1:8000,::1')),
Настройте свой
config/cors.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Cross-Origin Resource Sharing (CORS) Configuration
|--------------------------------------------------------------------------
|
| Here you may configure your settings for cross-origin resource sharing
| or "CORS". This determines what cross-origin operations may execute
| in web browsers. You are free to adjust these settings as needed.
|
| To learn more: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
|
*/
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', '*'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
Настройте свой
config/session.php
/*
|--------------------------------------------------------------------------
| Session Cookie Domain
|--------------------------------------------------------------------------
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN', null),
В вашем
.env
добавьте следующее:
// Change .localhost this to whatever domain you are using
// Please note the leading '.'
SESSION_DOMAIN=.localhost
VUE_APP_API_URL= // the domain you are serving your Laravel app
Выполнить
php artisan config:clear
VUE ФРОНТЕНД
- В вашем интерфейсе создайте следующую структуру папок / файлов
@/src/services/api.js
api. js:
import axios from 'axios';
const apiClient = axios.create({
baseURL: 'http://your-site.dev',
withCredentials: true,
});
export default apiClient;
Для аутентификации ваш SPA должен сначала сделать запрос на
/sanctum/csrf-cookie
. Это устанавливает
XSRF-TOKEN
готовить ie. Этот токен необходимо отправлять при последующих запросах (ax ios обработает это автоматически). Сразу после этого вы захотите отправить запрос
POST
на ваш маршрут Laravel
/login
. В компоненте входа в систему Vue:
import Vue from 'vue'
import apiClient from '../services/api';
export default {
data() {
return {
email: null,
password: null,
loading: false,
};
},
methods: {
async login() {
this.loading = true; // can use this to triggle a :disabled on login button
this.errors = null;
try {
await apiClient.get('/sanctum/csrf-cookie');
await apiClient.post('/login', {
email: this.email,
password: this.password
});
// Do something amazing
} catch (error) {
this.errors = error.response && error.response.data.errors;
}
this.loading = false;
},
},