'NuxtJs app returns 401 after log in with laravel sanctum
I'm trying to build a PWA with NuxtJS and Laravel is in the backend for the API.
I use Laravel Sanctum for API auth and also I have NuxtJS auth module, I can login (I know this because it returns and sets all of the cookies) but when it's requesting to 127.0.0.8000/api/user auth it returns a 401 error.
Heres is my nuxtjs config
export default {
/*
** Nuxt rendering mode
** See https://nuxtjs.org/api/configuration-mode
*/
mode: 'universal',
/*
** Nuxt target
** See https://nuxtjs.org/api/configuration-target
*/
target: 'server',
server: {
host: 'localhost'
},
render: {
// working:
injectScripts: process.env.NODE_ENV === 'development'
// HMR not working:
// injectScripts: false,
},
/*
** Headers of the page
** See https://nuxtjs.org/api/configuration-head
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{charset: 'utf-8'},
{name: 'viewport', content: 'width=device-width, initial-scale=1'},
{hid: 'description', name: 'description', content: process.env.npm_package_description || ''}
],
link: [
{rel: 'icon', type: 'image/x-icon', href: '/favicon.ico'}
]
},
/*
** Global CSS
*/
css: [
'~/assets/storefront-ui',
'~/assets/storefront-ui-custom',
'~/assets/custom'
],
/*
** Plugins to load before mounting the App
** https://nuxtjs.org/guide/plugins
*/
plugins: [
{src: '~/plugins/helpers', mode: 'client'},
{src: '~/plugins/storefront-ui', mode: 'client'},
{src: '~/plugins/icons', mode: 'client'},
{src: '~/plugins/plugins', mode: 'client'}
],
/*
** Auto import components
** See https://nuxtjs.org/api/configuration-components
*/
components: true,
/*
** Nuxt.js dev-modules
*/
buildModules: [
// Doc: https://github.com/nuxt-community/nuxt-tailwindcss
'@nuxtjs/tailwindcss',
],
/*
** Nuxt.js modules
*/
modules: [
// Doc: https://axios.nuxtjs.org/usage
'@nuxtjs/axios',
'@nuxtjs/pwa',
'@nuxtjs/auth',
],
/*
** Axios module configuration
** See https://axios.nuxtjs.org/options
*/
axios: {
baseURL: "http://localhost:8000",
credentials: true
},
auth: {
redirect: {
login: '/login',
logout: '/',
callback: '/login',
home: '/'
},
strategies: {
local: {
endpoints: {
login: { url: '/login', method: 'post', propertyName: false },
user: { url: '/api/user', method: 'get', propertyName: false }
},
tokenRequired: false,
tokenType: false
}
},
localStorage: false
},
router: {
middleware: ['auth']
},
//
/*
** Build configuration
** See https://nuxtjs.org/api/configuration-build/
*/
build: {
transpile: [/^@storefront-ui/],
postcss: {
// Add plugin names as key and arguments as value
// Install them before as dependencies with npm or yarn
plugins: {
// Disable a plugin by passing false as value
'postcss-url': true,
'postcss-nested': {},
'postcss-responsive-type': {},
'postcss-hexrgba': {},
"postcss-preset-env": {
stage: 0,
},
"rucksack-css": {}
},
preset: {
// Change the postcss-preset-env settings
autoprefixer: {
grid: true
}
}
}
}
}
Here is my login.vue
<template>
<div class="flex h-screen items-center justify-center">
<form ref="loginform" @submit.prevent="login()" class="w-1/4 mx-auto p-4">
<h1 class="font-semibold mb-2 text-xl">
Login
</h1>
<div class="mb-4">
<label for="email" class="block mb-1 text-sm">Email</label>
<input
type="email"
name="email"
class="w-full border rounded px-3 py-2"
required
/>
</div>
<div class="mb-4">
<label for="password" class="block mb-1 text-sm">Password</label>
<input
type="password"
name="password"
class="w-full border rounded px-3 py-2"
required
/>
</div>
<button
type="submit"
class="bg-blue-500 text-white font-semibold py-2 px-10 w-full rounded"
>
Login
</button>
</form>
</div>
</template>
<script>
export default {
data() {
return {
error: {},
};
},
middleware: 'auth',
mounted() {
// Before loading login page, obtain csrf cookie from the server.
this.$axios.$get('/sanctum/csrf-cookie');
},
methods: {
async login() {
this.error = {};
try {
// Prepare form data
const formData = new FormData(this.$refs.loginform);
// Pass form data to `loginWith` function
await this.$auth.loginWith('local', { data: formData });
// Redirect user after login
this.$router.push({
path: '/',
});
} catch (err) {
this.error = err;
// do something with error
}
},
},
};
</script>
The routes/api.php
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();
});
And my cors.php
<?php
return [
'paths' => ['api/*', 'sanctum/csrf-cookie', 'login', 'logout'],
'allowed_methods' => ['*'],
'allowed_origins' => ['http://localhost:3000'],
'allowed_origins_patterns' => [],
'allowed_headers' => ['*'],
'exposed_headers' => [],
'max_age' => 0,
'supports_credentials' => true,
];
Solution 1:[1]
The problem was in my Laravel .env configuration
Solution 2:[2]
if you are on localhost you need to add this in env file
SESSION_DOMAIN=127.0.0.1
SANCTUM_STATEFUL_DOMAINS=127.0.0.1:3000
Solution 3:[3]
do check your APP_URL
settings in .env
file as well. this can also cause 401. as this is used in session cookie key generation for session authentications.
in my case its value is:
APP_URL='https://example.com/api'
but i think APP_URL='http://example.com'
will also work though i didn't tested it. for me with /api
feels better as it is actually where the backend is.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Aimal Amiri |
Solution 2 | |
Solution 3 | rajesh_chaurasiya |