Как исправить ошибку «401 Несанкционированный» в Laravel 8 Sanctum и VueJS 3?

#laravel #vue.js #axios #laravel-sanctum

Вопрос:

Итак, у меня есть этот Laravel 8 проект VueJS 3 во внешнем интерфейсе, и я запускаю его на своем локальном
хосте И использую Sanctum для аутентификации.
Процесс входа и регистрации работает нормально, но когда я захожу на панель мониторинга и пытаюсь что-то добавить в свою базу данных, это выдает 401 Unauthorized ошибку.

Ларавель:

ИЗМЕНИТЬ: Пользовательский контроллер

 public function login(Request $request)
    {
        $credentials = [
            'email' => $request->email,
            'password' => $request->password,
        ];

        if (Auth::attempt($credentials)) {
            $success = true;
            $user = User::where('email', $credentials['email'])->first();
            $token = $user->createToken("authToken")->plainTextToken;
        } else {
            $success = false;
        }

        $response = [
            'success' => $success,
            'access_token' => $token,
        ];
        return response()->json($response);
    }
 

web.php

 Route::get('/{any}', function () {
    return view('welcome');
})->where('any', '.*');
 

api.php

 // Auth
Route::post('login', [UserController::class, 'login']);
Route::post('register', [UserController::class, 'register']);
Route::post('logout', [UserController::class, 'logout'])->middleware('auth:sanctum');

// Niveau
Route::group(['prefix' => 'niveaux', 'middleware' => 'auth:sanctum'], function () {
    Route::get('/', [NiveauScolaireController::class, 'index']);
    Route::post('add', [NiveauScolaireController::class, 'add']);
    Route::get('edit/{id}', [NiveauScolaireController::class, 'edit']);
    Route::post('update/{id}', [NiveauScolaireController::class, 'update']);
    Route::delete('delete/{id}', [NiveauScolaireController::class, 'delete']);
});  
 

cors.php

 'paths' => ['api/*', 'sanctum/csrf-cookie'],
'allowed_methods' => ['*'],
'allowed_origins' => ['*'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
 

sanctum.php

 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    'SANCTUM_STATEFUL_DOMAINS',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
    env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),  
 

session.php

 'domain' => env('SESSION_DOMAIN', null),
 

So that’s what I set up for the Laravel side.

VueJS

app.js

 import { createApp } from "vue";
import App from "./App.vue";
import router from "./Router/index";
import axios from "axios";
const app = createApp(App);
app.config.globalProperties.$axios = axios;
app.use(router);
app.mount("#app");
 

bootsrap.js

 window.axios = require("axios");
window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
windoow.axios.defaults.withCredentials = true;
 

Компонент входа в систему

 this.$axios.get("/sanctum/csrf-cookie").then((res) => {
    this.$axios
        .post("api/login", {
              email: this.email,
              password: this.password,
        })
        .then((res) => {
            if (res.data.success) {
                this.$router.push({ name: "Dashboard" });
            } else {
                console.log("Error: "   res.data.message);
            }
        })
        .catch(function (error) {
            console.log("error :>> ", error);
        });
    });
 

Здесь мой запрос sanctum/csrf-cookie идет хорошо, и я получу файлы cookie, логин работает нормально, он получает пользователя из базы данных, а затем перенаправляет меня на панель мониторинга.

Проблема
Теперь вот, когда я пытаюсь отправить запрос (api/niveaux/add) , запрос отправляется, но я получаю 401 Unauthorized ошибку с {"message":"Unauthenticated."} ответом.

Компонент панели мониторинга

 this.$axios
    .post("api/niveaux/add", {
        nom: this.niveau,
    })
    .then((res) => {
        if (res.data.success) {
            alert(res.data.message);
        } else {
            alert(res.data.message);
        }
    })
    .catch(function (error) {
        console.log("error :>> ", error);
    });
 

Комментарии:

1. спасибо за вопрос. У меня та же проблема

Ответ №1:

вам нужно отправить вам access_token каждый запрос, который есть middleware('auth:sanctum') в laravel. вы можете найти access_token внутри файла cookie, который вы получаете после входа в систему. (может иметь другое имя, например token )

 axios.defaults.headers.common['Authorization'] = `Bearer ${access_token}` 
 

или

 axios.defaults.headers.common['Authorization'] = `${access_token}` 
 

должен сделать этот трюк

Комментарии:

1. Я пробовал, но это не работает, я отредактировал свой вопрос и добавил пользовательский контроллер, и в свой boostarp.js файл я внес изменения, о которых вы мне сказали, но все равно не повезло

Ответ №2:

Я думаю, что вы получаете доступ через порт localhost 8000, но в вашем параметре с отслеживанием состояния в конфигурации sanctum его нет localhost:8000 . Конфигурация использует $_SERVER[‘ИМЯ_СЕРВЕРА’], поэтому она фактически ищет точное содержимое при доступе к нему.

sanctum.php

 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    'SANCTUM_STATEFUL_DOMAINS',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
    'localhost:8000',
    env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))), 
 

Комментарии:

1. Я попробовал, все та же ошибка «401», у вас есть какие-либо другие идеи, которые могут вызвать эту проблему

Ответ №3:

заметил здесь опечатку:

 
window.axios = require("axios");
window.axios.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
windoow.axios.defaults.withCredentials = true;
 

последнее «виндоу» было написано неправильно.

Ответ №4:

Когда я столкнулся с этим, я отследил и сравнил изменения с существующим рабочим проектом

 'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
    'SANCTUM_STATEFUL_DOMAINS',
    'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
    env('APP_URL') ? ',' . parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))), 
 

в config/sanctum.php был изменен, я просто заменил его старым кодом

 'stateful' => explode(',', env(
    'SANCTUM_STATEFUL_DOMAINS',
    'localhost,127.0.0.1,127.0.0.1:8000,::1,' . parse_url(env('APP_URL'), PHP_URL_HOST)
)),