laravelvue.jsaxioslaravel-sanctum

How do I fix the "401 Unauthorized" error with Laravel 8 Sanctum and VueJS 3?


So I have this Laravel 8 project with VueJS 3 in the frontend, and I'm running it on my localhost
And I'm using Sanctum for my authentication.
The Login and Sign Up process works fine, but when I go to a dashboard and I try to add something to my database it gives me the 401 Unauthorized error.

Laravel:

EDIT: UserController

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;

Login component

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);
        });
    });

Here my request for sanctum/csrf-cookie is going well and I’ll receive Cookies, the login works fine, it gets the user from the database, and then it redirects me to the dashboard.

Problem
Now here when I try to send a request to (api/niveaux/add) the request is sent, but I get a 401 Unauthorized error with a {"message":"Unauthenticated."} response.

Dashboard component

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);
    });

Solution

  • you need to send you access_token in every request that has middleware('auth:sanctum') in laravel. you can find access_token inside the cookie you get after logging in. (might have different name like token)

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

    or

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

    gotta do the trick