I have integrated the nuxt/auth module with the Laravel Sanctum provider and the login works fine, the problem is when I want to remember the user.
I sent to the api a boolean parameter with the name remember and in the api the option remember is assigned well, the token is saved in the user table and the nuxt/auth module sets the cookie remember_web_59ba36addc2b2b2b2f9401580f014c7f58ea4e30989d but if I set the SESSION_LIFETIME to 5 minutes when I refresh the page after 5 minutes the user is disconnected and does not keep the session until 2027 which is the date assigned to the cookie, I attach an image with the dates of the cookies.
nuxt.config.js
auth: {
strategies: {
'laravelSanctum': {
provider: 'laravel/sanctum',
url: process.env.BASE_URL
},
}
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
baseUrl: process.env.BASE_URL,
credentials: true
},
And on the login page
this.$auth.loginWith('laravelSanctum', {
data: this.form
})
The cookies with the times
in nuxt.config.js
axios: {
baseURL: 'http://localhost/twillo-api/api'
},
auth: {
redirect: {
login: '/account/login',
callback: '/account/login',
home: '/'
},
strategies: {
local: {
token: {
property: 'data.accessToken',
required: true,
global: true,
maxAge: 43200,
type: 'Bearer',
name: 'Authorization'
},
user: {
property: 'user',
autoFetch: false
},
endpoints: {
login: { url: '/login', method: 'post' },
},
localStorage: {
prefix: 'auth.'
}
}
},
},
And on the login page
setUniversal will store user record in cookie.
this.$auth.loginWith('local', { data: payload })
.then(response => {
if(response.data.status) {
this.$auth.setUser(response.data.data.userData)
this.$auth.$storage.setUniversal('user', response.data.data.userData)
this.$auth.$storage.setUniversal('loggedIn', true)
}else {
this.invalidCredential= response.data.message
}
}).catch(error => {
this.backendErrors = error.response.data.errors
})
Errors
Access to XMLHttpRequest at 'https://api.domain.com/api/register' from origin 'https://nuxt-app.domain.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
I am using PHP Laravel for backend API development and Nuxt.js for my frontend application.
Laravel Sanctum Installation
composer require laravel/sanctum
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
php artisan migrate
In App/Http/Kernel.php to api middleware group, Add Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class
In config/cors.php, set supports_credentials to true
In .env file, add SESSION_DOMAIN=.domain.com and SANCTUM_STATEFUL_DOMAINS=nuxt-app.domain.com
In routes/api.php, Modify Route::middleware('auth:sanctum')
nuxt.config.js
{
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth-next'
],
axios: {
credentials:true,
proxy: true
},
proxy: {
'/api': {
target: 'https://api.domain.com',
pathRewrite: { '^/api': '/' }
}
},
auth: {
strategies: {
laravelSanctum: {
provider: "laravel/sanctum",
url: "https://api.domain.com",
endpoints: {
login: {
url: "/api/login",
method: "POST"
},
logout: {
url: "/api/logout",
method: "POST"
},
user: {
url: "/api/user"
}
},
user: {
property: false
}
}
},
redirect: {
login: "/login",
logout: "/login",
home: "/dashboard"
}
},
}
Register.vue
<script>
export default {
middleware: ["guest"],
head() {
return {
title: "Register",
};
},
data() {
return {
form: {
name: "",
email: "",
password: "",
password_confirmation: "",
},
errors: [],
};
},
methods: {
async register() {
await this.$axios.get("https://api.domain.com/sanctum/csrf-cookie");
await this.$axios
.$post("https://api.domain.com/api/register", this.form)
.then((response) => {
console.log(response);
this.$router.push("/login");
})
.catch((error) => {
this.errors = error.response.data.errors;
console.log(this.errors);
});
},
},
};
</script>
Is there anything else to do? If 'Yes' then, please guide me.
Otherwise, Why it's not working on the production server? Does anyone know how to fix this error?
I'm authenticating with Laravel Passport and my front end has been implemented with nuxt.
I receive the following 404 error when sending a request with nuxt Auth to Backend:
{"message":"","exception":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException","file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\AbstractRouteCollection.php","line":43,"trace":[{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\RouteCollection.php","line":162,"function":"handleMatchedRoute","class":"Illuminate\\Routing\\AbstractRouteCollection","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php","line":647,"function":"match","class":"Illuminate\\Routing\\RouteCollection","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php","line":636,"function":"findRoute","class":"Illuminate\\Routing\\Router","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\Router.php","line":625,"function":"dispatchToRoute","class":"Illuminate\\Routing\\Router","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php","line":166,"function":"dispatch","class":"Illuminate\\Routing\\Router","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":128,"function":"Illuminate\\Foundation\\Http\\{closure}","class":"Illuminate\\Foundation\\Http\\Kernel","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php","line":21,"function":"Illuminate\\Pipeline\\{closure}","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull.php","line":31,"function":"handle","class":"Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":167,"function":"handle","class":"Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest.php","line":21,"function":"Illuminate\\Pipeline\\{closure}","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\TrimStrings.php","line":40,"function":"handle","class":"Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":167,"function":"handle","class":"Illuminate\\Foundation\\Http\\Middleware\\TrimStrings","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize.php","line":27,"function":"Illuminate\\Pipeline\\{closure}","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":167,"function":"handle","class":"Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance.php","line":86,"function":"Illuminate\\Pipeline\\{closure}","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":167,"function":"handle","class":"Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\fruitcake\\laravel-cors\\src\\HandleCors.php","line":38,"function":"Illuminate\\Pipeline\\{closure}","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":167,"function":"handle","class":"Fruitcake\\Cors\\HandleCors","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\fideloper\\proxy\\src\\TrustProxies.php","line":57,"function":"Illuminate\\Pipeline\\{closure}","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":167,"function":"handle","class":"Fideloper\\Proxy\\TrustProxies","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Pipeline\\Pipeline.php","line":103,"function":"Illuminate\\Pipeline\\{closure}","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php","line":141,"function":"then","class":"Illuminate\\Pipeline\\Pipeline","type":"->"},{"file":"D:\\temopo\\api-test\\vendor\\laravel\\framework\\src\\Illuminate\\Foundation\\Http\\Kernel.php","line":110,"function":"sendRequestThroughRouter","class":"Illuminate\\Foundation\\Http\\Kernel","type":"->"},{"file":"D:\\temopo\\api-test\\public\\index.php","line":52,"function":"handle","class":"Illuminate\\Foundation\\Http\\Kernel","type":"->"},{"file":"D:\\temopo\\api-test\\server.php","line":21,"function":"require_once"}]}
my nuxt auth and axios config:
axios: {
baseURL: 'http://localhost:8000/',
header:{
'content-type':'application/json'
}
},
auth: {
strategies: {
laravelPassport: {
provider: 'laravel/passport', // Using nuxtAuth laravel passport provider
url: 'http://localhost:8000/',
clientId: '1',
client_secret: '****MPZAMzicKGjByb1hnTciqLScP7KUr7CyKgf', //Is the same as the value inside the database
grantType: 'password'
},
}
},
nuxt login mehtod and data
data() {
return {
login: {
username: '',
password: '',
},
}
},
methods: {
async loginMethod() {
await this.$auth.loginWith('laravelPassport',{ data: this.login })
},
},
Laravel API routes
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Auth\LoginControlle;
use \App\Http\Controllers\Auth\SignupControlle;
Route::post('/login',LoginControlle::class);
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
i had this problem and solved after one week.
in my opinion, use the proxy same below codes: let's coding ;-)
nuxt.config.js
axios: {
proxy: true,
baseURL: process.env.API_URL,
},
proxy: {
'/backend': {
target: process.env.API_URL,
pathRewrite: { '^/backend': '/' },
},
},
auth: {
redirect: {
home: '/profile',
login: '/profile',
logout: '/',
},
strategies: {
laravelPassportPasswordGrant: {
name: 'authMakeup',
provider: 'laravel/passport',
url: '/backend',
endpoints: {
token : '/api/v1/confirmCode',
user:{url:'/api/v1/user', method:'get'},
logout:{url: '/api/v1/logout', method: 'post'}
},
clientId: process.env.PASSPORT_CLIENT_ID,
clientSecret: process.env.PASSPORT_CLIENT_SECRET,
grantType: 'password',
},
},
},
in .env file:
API_URL="http://localhost:8000"
PASSPORT_CLIENT_ID=************
PASSPORT_CLIENT_SECRET=***********************
using:
this.$auth.loginWith("authMakeup", {
data: params
});
if you want to login by user & password not require override token in endpoint section.
but i had want to login by mobile, override it to custom route example:
token : '/api/v1/confirmCode',
Nuxt js NOTE: It is highly recommended to use proxy to avoid CORS and same-site policy issues.
I couldn't understand the use of "target" and "pathRewrite
" in the proxy.
who can describe them?
if my backend(laravel) URL be localhost:8000 and my frontend(Nuxt) URL be localhost:3000 then how should I config it?
You may use Axios proxy in NuxtJS like this:
export default {
axios: {
credentials: true,
proxy: true,
debug: process.env.NODE_ENV !== 'production',
},
proxy: {
'/api/': process.env.API_URL,
},
auth: {
redirect: {
login: '/auth/login',
logout: '/auth/login',
callback: '/auth/login',
home: '/feed',
},
strategies: {
laravelSanctum: {
provider: 'laravel/sanctum',
url: 'api', // note the URL here.
endpoints: {
login: {
url: '/auth/login',
},
logout: {
url: '/auth/logout',
},
user: {
url: '/auth/me',
},
},
},
}
}
}
I couldn't understand the use of "target" and "pathRewrite " in the proxy.
Let's say your API_URL is localhost:8000.
If you write proxy config like this:
proxy: {
'/api': process.env.API_URL,
},
It will add /api at the end of the URL. So your API_URL will be localhost:8000/api.
Now you may call API request with Axios like this:
this.$axios.$get('api/me');
In the behind, it will call to this URL: localhost:8000/api/me.
If you write your proxy config like this:
proxy: {
'/api': {
target: process.env.API_URL,
pathRewrite: { '^/api': '/' }
}
},
It will remove /api from the end of the URL. So your API_URL will be localhost:8000.
Now you may call API request with Axios like this:
this.$axios.$get('api/me');
In the behind, it will call to this URL: localhost:8000/me.
Enjoy :)
I have a Nuxtjs app which authenticates fine. But I need the user details for filling out a form automatically. I see that the app calls /user endpoint on every reload. I want to insert a $store in its callback to store the user data in $store.
computed: {
getUser () {
return this.$store.state.user.user;
}
},
methods: {
setUser (data) {
this.$store.commit('user/add', data)
},
}
NUXT Config:
auth: {
strategies: {
local: {
endpoints: {
login: {
url: '/auth/login',
method: 'post',
propertyName: 'access_token'
},
logout: {
url: '/auth/logout',
method: 'post'
},
user: {
url: '/auth/user',
method: 'get',
propertyName: false
},
tokenRequired: true
}
}
}
}
Is it possible to intercept the $auth.fetchUser or whatever method $auth is using to fetch the api/user endpoint on every reload?
I solved it by using auth and vuex methods. I don't need to intercept the call. Just use
this.$auth.user
or
this.$store.state.auth.user;
Learning Nuxt/Vuejs is fun.