Related
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
})
I inherited a web project from another developer who's left the company. It is built with nuxtjs and laravel, neither of which I am strong with.
In the web project, after a user goes to a login screen, types in email and password, and presses save, I can see in my developer tools that the nuxtjs framework sends a {email: "user#email.com", password: "password"} to the laravel api at https://example.project.com/api/login. The laravel api then returns a 200 response with this payload { data: { message: "Login successful.", token: "50|Fs88RPU7HON1LnBskm35O9txG0OnXDiG3x4XWILJ" }}. Everything is great so far!
Immediately after the 200 response above, NuxtJS sends another request to https://example.project.com/api/auth/user in an attempt to get information about this user. Nginx gives a 401 response. My first suspicion for why this happens is because NuxtJS sent an Authorization: Bearer undefined as shown in this screenshot of my browser dev tools
I've seen other situations with Authorization: Bearer [object object].
I want to know how does NuxtJS decide what value to provide to the Authorization http header? This is my current nuxt.config.js
export default {
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'Blah',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.png' }],
},
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules: https://go.nuxtjs.dev/config-modules
modules: [
// https://go.nuxtjs.dev/axios
'#nuxtjs/axios',
'#nuxtjs/auth'
],
auth: {
redirect: {
login: '/login',
logout: '/',
callback: '/api/login',
home: '/'
},
strategies: {
local: {
endpoints: {
login: { url: '/api/login'},
user: { url: '/api/auth/user'}
},
}
},
localStorage: true
},
proxy: {
'/api': {
target: 'https://example.project.com/',
pathRewrite: { '^/api': '' },
},
},
// Axios module configuration: https://go.nuxtjs.dev/config-axios
axios: {
baseURL: 'https://example.project.com/',
credentials: true,
headers : {
common: {
'Accept' : 'application/json'
}
}
},
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {
}
}
And also, this is the line of code in pages/login.vue that starts the login process:
await this.$auth.loginWith('local', { data: {email:"user#email.com",password:"password"} });
Simply add Authorization header as default header right after authorization request. Assuming that server sends access token in response the code might look like this:
const response = await this.$auth.loginWith('local', {
data: {
email: "user#email.com",
password:"password"
}
})
const { token } = response;
axios.defaults.headers.common = { Authorization: `Bearer ${token}` };
change your strategy as below to set property name of the token being returned in response.
strategies: {
local: {
token: {
property: 'token'
},
endpoints: {
login: { url: '/api/login'},
user: { url: '/api/auth/user'}
},
}
},
It will include the authorization header in all your requests using $axios.
also you might need to set propery of the user which you are returning from backend also.
This is done by a library in the background. #nuxtjs/auth or #nuxtjs/auth-next will set the token depending on your config in nuxt.config.ts.
You can find the token in the local storage in auth._token.<strategy>. To use a Bearer token in the subsequent userinfo request you might need to set:
nuxt.config.ts
auth: {
strategies: {
local: {
token: {
type: 'Bearer',
}
}
}
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',
I am building a web application with django-rest-framework and extjs5.
Obviously i faced problems with django's csrf token, which i had to inlude in Extjs's Ajax requests.
But while i implemented POST method successfully, it seems that my implementation doesn't work for PUT and DELETE method.
My POST method code:
onSaveRecordBtnClick: function(){
Job_Name = this.lookupReference('Job_Name').getValue();
var csrf = Ext.util.Cookies.get('csrftoken');
Ext.Ajax.request({
url: '/jobs_api/job/',
method: "POST",
params: {
Job_Name: Job_Name,
'csrfmiddlewaretoken': csrf
},
success: function(conn, response, options, eOpts) {
var result = MyApp.util.Util.decodeJSON(conn.responseText);
if (result.success) {
alert('Job Submission Successfull');
}
else {
MyApp.util.Util.showErrorMsg(conn.responseText);
}
},
failure: function(conn, response, options, eOpts) {
MyApp.util.Util.showErrorMsg(conn.responseText);
}
});
}
This works perfectly, but when i try PUT or DELETE method i keep getting:
Request Method:DELETE
Status Code:403 FORBIDDEN
{"detail":"CSRF Failed: CSRF token missing or incorrect."}
My DELETE method:
onJobDblClick : function(grid, record, index, eOpts) {
var job_id = record.id;
var csrf = Ext.util.Cookies.get('csrftoken');
Ext.Ajax.request({
url: '/jobs_api/job/' + job_id + '/',
method: "DELETE",
params: {
'id': job_id,
'csrfmiddlewaretoken': csrf
},
success: function(conn, response, options, eOpts) {
var result = MyApp.util.Util.decodeJSON(conn.responseText);
if (result.success) {
alert('Job Deleted Successfully');
}
else {
MyApp.util.Util.showErrorMsg(conn.responseText);
}
},
failure: function(conn, response, options, eOpts) {
MyApp.util.Util.showErrorMsg(conn.responseText);
}
});
}
My job model is:
Ext.define('MyApp.model.Job', {
extend: 'MyApp.model.Base',
fields: [
{ name: 'id', type: 'int' },
{ name: 'Job_Name', type: 'string' },
],
proxy: {
type: 'rest',
url: '/jobs_api/job/',
reader: {
type: 'json',
rootProperty: 'data'
}
}
});
I don't know why this is happening. Please help!!