I am trying to use Nuxt/auth, but run into problem with session saving in localStorage.
Login.vue
methods: {
sendLoginLink() {
this.$auth.loginWith('local', {
data: {
username: "test#gmail.com",
password: "testpassword"
}
}).then((date) => {
console.log("data", date)
}).catch((err) => {
console.error("err", err)
})
}
Nuxt.config.js
auth: {
strategies: {
local: {
endpoints: {
login: { url: '/dashboard', method: 'post', propertyName: 'token' }
},
tokenType: ''
}
}
axios: {
baseURL: 'http://localhost:1234'
},
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth-next',
]
When the user logs in, the function sendLoginLink is called and throw error in console:
Which means that the auth-token is so large that it cannot be stored in localStorage, but all other things related to this function are saved in localStorage. For example:
I googled a lot but didn't find a good solution to the problem. For example, I tried to clear all localStorage memory before running sendLoginLink() function but the result is the same. Different browsers have the same problem
Related
My problem is, that login/logout works perfectly on my localhost, but as soon as I deploy it on a server I got 301 and 405 errors, with the "The GET method is not supported for this route. Supported methods: POST" message and I cant figure it out why is that.
My nuxt.config.js:
},
auth: {
strategies: {
local: {
user: {
property: 'data'
},
token: {
maxAge: 86400,
global: true
},
endpoints: {
login: { url: '/api/auth/login/', method: 'post' },
logout: { url: '/api/auth/logout/', method: 'post' },
user: { url: '/api/auth/user/', method: 'get' }
}
},
}
},
build: {
My login method:
async login() {
this.errors = {};
try {
await this.$auth.loginWith('local', { data: this.loginForm });
...
} catch (error) {
if (error.response.status === 401) {
this.inactive = error.response.data.message;
}
this.errors = error?.response?.data?.errors;
}
},
My Laravel api.php:
Route::group(['prefix' => 'auth'], function () {
Route::post('login/', [AuthController::class, 'login']);
Route::post('register', [AuthController::class, 'register']);
Route::post('set-password', [AuthController::class, 'setPassword']);
Route::group(['middleware' => ['auth:sanctum']], function () {
Route::get('user/', [AuthController::class, 'user']);
Route::post('logout/', [AuthController::class, 'logout']);
Route::post('password-reset', [AuthController::class, 'passwordReset']);
});
});
And i will attach my network tab from my browser (first is on localhost/working, second one is on a server/not working):
I don't know what I'm messing up but after several days of debugging I'm hopeless. I've emptied every possible caches on the backend side so I'm thinking thats not the problem. But hopefully somebody else will be much more clever than me and can tell me what's going on.
I have two websites. On the first the user logs in (creating a local storage value), on the second (the one I am trying to program) the storage value is rechecked for login but is returning false. What do I need to modify?
NB: I know this is a strange situation, but there is a reason for it so it cannot be changed.
In strategies I have...
local: {
token: { required: false, maxAge: 90000 },
user: { autoFetch: false, property: false },
endpoints: {
user: false,
login: false,
logout: false,
},
},
... property being set to false as the storage value is a more complex version of {"firstName":"abc","lastName":"def"}, i.e. not in a user field.
In the main vue file I have...
created() {
var savedData = localStorage.getItem("ngStorage-user");
if (savedData !== null) {
alert(savedData); // Displays the string that I expect.
this.$auth.setUser(JSON.parse(savedData)); // The setUser call.
alert(this.$auth.user.firstName); // Displays 'abc'.
alert(this.$auth.loggedIn); // Displays false
}
}
PS: I have reviewed the similar queries, but none seems to match this.
====
Addendum: I have possibly solved this, and improved it at the same time by checking that the token is valid.
Added a call to tokencheck in the API which checks the token and returns minimal user details.
local: {
token: { required: false, maxAge: 90000, property: "token" },
user: { autoFetch: false, property: false },
endpoints: {
user: { url: `${process.env.API_URL}tokencheck` },
login: false,
logout: false,
},
},
And then in Vue
created() {
var savedData = localStorage.getItem("ngStorage-user");
if (savedData !== null) {
var parsedSaveData = JSON.parse(savedData);
this.$auth.setUserToken(parsedSaveData.token) // Which calls the 'user' endpoint
.then(res => { this.$auth.setUser(res.data); })
.catch(() => { this.error = true; });
}
}
I'm new to Nuxt Auth and express session, when I perform this.$auth.loginWith('local', { data: '' }), I will set req.session.loggedIn = true in the server, and I can see my req.session.id = 'xxx' for example.
After that, the nuxt auth will make another call to /api/auth/user, but I can see the sessionID has been changed, and req.session.loggedIn was undefined.
How can I maintain the same session for every request?
Below is my config
auth: {
strategies: {
local: {
token: {
required: false,
type: false
},
endpoints: {
login: { url: '/api/auth/login', method: 'POST' },
logout: { url: '/api/auth/logout', method: 'POST' },
user: { url: '/api/auth/user', method: 'get' }
}
}
}
},
I'm using v5
"#nuxtjs/auth-next": "5.0.0-1616003482.75c20e6",
I'm using NuxtJs v2.13 with its auth module and Laravel with passport for my backend. for login i use the documented method:
async signIn(formData){
await this.$auth.loginWith('local',{
data: formData
})
if(this.$auth.user.depth > 1){
this.goTo('/cms/product')
}else{
this.goTo('/')
}
}
when the email or password is wrong it send me too nuxt error page! i should remain on login page.
what should i do!!?
BTW, i gonna use vee-validate on my form too. and this is my auth config on nuxt.config.js:
auth: {
strategies: {
local: {
endpoints: {
login: { url: 'auth/login', method: 'post', propertyName: '' },
logout: { url: 'auth/logout', method: 'post' },
user: { url: 'auth/info', method: 'get', propertyName: 'data' }
}
}
},
redirect: {
login: '/login',
logout: '/',
callback: '/login',
home: '/'
},
cookie: {
prefix: 'auth.',
options: {
path: '/',
maxAge: process.env.AUTH_COOKIE_MAX_AGE
}
}
},
Nuxt is redirecting because the error isn't being handled. You can simply wrap this code in an error handler. It's also good to put this code near the login component or page so you can use the status code of the error to display some meaningful response to the user, e.g. that the credentials were invalid.
try {
await this.$auth.loginWith('local', {
data: formData,
})
if (this.$auth.user.depth > 1) {
this.goTo('/cms/product')
} else {
this.goTo('/')
}
} catch (error) {
if (error.response) {
// Get the error status, inform the user of the error.
}
// Unexpected error, tell the user to try again later.
}
Since the #nuxtjs/auth package requires the #nuxtjs/axios package you can also read about intercepting errors on a global level with Axios Interceptors. I personally use try/catch blocks at the method level and use interceptors for catching 401 Unauthenticated errors and deleting the user information from Vuex.
I'm trying to catch the error response for #nuxtjs/auth but it doesn't seem to return anything but undefined.
It refuses to login if I include the user so I want to know why it's returning undefined.
CONFIG:
auth: {
strategies: {
local: {
endpoints: {
login: {
url: 'http://127.0.0.1:80/api/login',
method: 'post',
propertyName: 'token'
},
logout: false,
user: {
url: 'http://127.0.0.1:80/api/me',
method: 'get',
propertyName: undefined
}
},
tokenRequired: true,
tokenType: 'bearer',
}
},
plugins: [
'#/plugins/auth.js'
]
},
PLUGIN:
export default function ({ app }) {
app.$auth.onError((error, name, endpoint) => {
console.error(name, error)
});
}
VIEW FUNCTION:
- both handleSuccess and handleFailure returns undefined.
login() {
this.toggleProcessing(0);
let payload = {
username: 'admin',
password: 'admin123'
}
let handleSuccess = response => {
console.log(response);
this.toggleProcessing(0);
}
let handleFailure = error => {
console.log(error);
this.toggleProcessing(0);
}
this.$auth.loginWith('local', { data: payload }).then(handleSuccess).catch(handleFailure);
},
You can use e.response
async login() {
try {
const login = {
username: this.username,
password: this.password
}
let response = await this.$auth.loginWith('local', { data: login })
console.log('response', response)
} catch (e) {
console.log('Error Response', e.response)
}
}
I fell into the same problem and after spending some time i found out a very good way to catch the response. The solution is to use the axios interceptor. Just replace your plugin file code with the following
export default function ({$axios, $auth}){
$axios.interceptors.response.use(function (response) {
// Do something with response data
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
}
I'm not sure initially what might be wrong here because I can't see the complete nuxt.config.js and your full component but here are a few things to check:
#nuxtjs/axios is installed
Both axios and auth modules are registered in the modules section of nuxt.config.js:
modules: [
'#nuxtjs/axios',
'#nuxtjs/auth'
]
Also, ensure the middleware property for auth is set in the component/page component.
Ensure you're following the documentation on this page: https://auth.nuxtjs.org/getting-starterd/setup
Ive been using try -> this.$auth.loginWith to catch error server response with #nuxtjs/auth.
login() {
const data = { form };
try {
this.$auth
.loginWith("local", { data: data })
.then(api => {
// response
this.response.success = "Succes";
})
.catch(errors => {
this.response.error = "Wrong username/password";
});
} catch (e) {
this.response.error = e.message;
}
},
Specify the token field in the nuxt.config
strategies: {
local: {
endpoints: {
login: { // loginWith
url: "auth/login",
method: "post",
propertyName: "data.token" // token field
},
user: { // get user data
url: "auth/user",
method: "get",
propertyName: "data.user"
},
}
}
},
modules: ["#nuxtjs/axios", "#nuxtjs/auth"],