Closed Geminii closed 6 years ago
This issue as been imported as question since it does not respect auth-module issue template. Only bug reports and feature requests stays open to reduce maintainers workload. If your issue is not a question, please mention the repo admin or moderator to change its type and it will be re-opened automatically. Your question is available at https://cmty.app/nuxt/auth-module/issues/c155.
@Geminii I'm running into the same issue. Did you ever find the cause?
Me too, I have spent so much time with this I could have implemented my own auth system by now... I was hoping this would be more intuitive.
I came up with this which seems to work as I would have expected the redirects to work out of the box.
export default function ({ app }) {
const oldLogout = app.$auth.logout.bind(app.$auth)
const oldLogin = app.$auth.login.bind(app.$auth)
app.$auth.logout = (...args) => {
const _ = oldLogout(...args)
_.then(() => app.$auth.redirect('logout'))
return _
}
app.$auth.login = (...args) => {
// sometimes doesn't work when the user tries to get to the admin page
// before being logged in.
const _ = oldLogin(...args)
_.then(() => {
app.$auth.redirect('home')
})
return _
}
}
I came up with this which seems to work as I would have expected the redirects to work out of the box.
export default function ({ app }) { const oldLogout = app.$auth.logout.bind(app.$auth) const oldLogin = app.$auth.login.bind(app.$auth) app.$auth.logout = (...args) => { const _ = oldLogout(...args) _.then(() => app.$auth.redirect('logout')) return _ } app.$auth.login = (...args) => { // sometimes doesn't work when the user tries to get to the admin page // before being logged in. const _ = oldLogin(...args) _.then(() => { app.$auth.redirect('home') }) return _ } }
@NoahCardoza Where did you make these changes in the configuration?
This lirbary seems dead. it's faster to create a few methods and states on vuex and manage the stuff alone...
@sayx I added this as an auth-module
plugin.
nuxt.config.js
...
auth: {
plugins: ['~/plugins/auth.js'],
strategies: {
local: {
endpoints: {
login: { url: '/api/login', method: 'post' },
logout: { url: '/api/logout', method: 'get' },
user: { url: '/api/user', method: 'get', propertyName: 'username' }
},
tokenRequired: false,
tokenType: false,
}
},
redirect: {
login: '/login',
logout: '/login',
home: '/admin',
user: '/admin',
},
}
...
~/plugins/auth.js
being what I shared earlier.
@ConsoleTVs I feel like the library is useful, it just didn't seem to function the way I thought it would.
I am having the same problem,
auth: {
rewriteRedirects: true,
strategies: {
local: {
endpoints: {
login: { url: 'user/login', method: 'post', propertyName: 'data.token' },
user: { url: 'user/me', method: 'get', propertyName: 'data' },
logout: false
}
},
facebook: {
client_id: process.env.FB_APP_ID,
userinfo_endpoint: 'https://graph.facebook.com/v2.12/me?fields=about,name,picture{url},email',
scope: ['public_profile', 'email'],
redirect_uri: process.env.FB_REDIRECT_URI
},
google: {
client_id: process.env.GOOGLE_APP_ID,
scope: ['profile', 'email'],
redirect_uri: process.env.GOOGLE_REDIRECT_URI
},
},
redirect: {
login: '/login',
logout: '/',
home: '/privacy',
}
},
A guarded route profile, when trying to access it withought being logged in it redirects to the login page, after login (on any strategy... local or oauth) it always redirects to /privacy instead of the original guarded route as per documentation.
Please note that even by default rewriteRedirects should be true i am making sure of it in the config options.
I can't actually get the auth module to redirect after login. It just never emits the routeChange event after I log in it seems. I can get it to redirect on logout, or from an authed page when not logged in.
auth: {
strategies: {
local: {
endpoints: {
login: {
url: '/login',
method: 'get',
propertyName: 'token'
},
logout: {
url: '/logout',
method: 'delete'
},
user: {
url: '/me',
method: 'get',
propertyName: 'data'
}
}
}
},
redirect: {
login: '/auth/login',
logout: '/',
home: '/',
callback: '/'
},
watchLoggedIn: true,
rewriteRedirects: true
},
I'm still not sure what callback is for in redirects, but I've changed it to every possible value I can think of, as well as omitting it, with no difference.
I've tried running as SSR and SPA, with no difference as well.
Duplicate of #134. See workaround in that thread which resolved the problem for me.
I actually found that when you set the property user on endpoints to false, it starts working as expected.
The thing is that is seems that the nuxt auth plugin waits this property to be defined to redirect to homepage. There is no need to make workarounds, but a PR may be welcome.
Here is my code:
auth: {
strategies: {
local: {
endpoints: {
login: { url: '/auth/login', method: 'post', propertyName: 'token' },
user: { url: '/auth/user', method: 'get', propertyName: false },
logout: { url: '/auth/logout', method: 'post' }
},
// tokenRequired: true,
// tokenType: 'Bearer'
}
},
redirect: {
login: '/public/login',
home: '/',
logout: '/public/login'
}
}
I've the same problem.
I'm using auth-module and when submitting the login form, I am redirected to the same login page, not to the requested page via a $router.push()...
Someone has an idea please?
async submitLogin() {
try {
// @ts-ignore
await this.$auth.loginWith('local', {
data: {
email: this.email,
password: this.password,
}
})
console.log('on push ici');
} catch (e) {
this.error = e.response.data.message
}
}
I think the issue is related to the default redirects.
If the redirects for 'logout' and 'home' are the same (as is the default), the internal redirect function gets confused because after a successful login, it always redirects to 'home' first and then checks for a stored redirect path if 'rewriteRedirects' is set to true.
However, if 'logout' and 'home' are the same path, the name of the path is set to 'logout' not 'home' so the actual redirect you want never occurs.
Changing the redirect for 'logout' seems to fix this issue.
{
auth: {
redirect: {
logout: '/logout',
home: '/'
}
}
}
Note that this needs to be a distinct path, the same path with query parameters, even with 'fullPathRedirect' set to true does not appear to fix this.
@AllanPinheiroDeLima thanks for the solution, my auth now work succesfully.
I got the same issue but got it fixed by put a forward slash in front of my urls
redirect: { login: '/public/login/', home: '/', logout: '/public/login/' }
instead of redirect: { login: '/public/login', home: '/', logout: '/public/login' }
N.B: Notice the forward slash.
Using the promise handler worked for me.
let data = {
username: this.username,
password: this.password
}
this.$auth.login({data: data})
.then(() => {
this.$router.push("/dashboard")
})
.catch((error)=> {
console.log(error)
})
Thank you @NoahCardoza, your solution worked like champ! :)
I was fighting with this error too and I solve it adding this line before redirect to the login
$auth.$storage.setUniversal('redirect', path)
I found this very hard to understand and its still not working as expected. Tried all the suggested solutions above. I will probably start building my own auth using a bit of vuex :/
@donmb1 that's what I had to do then but with the recent updates and fixes in the latest version. I think you can find your way around this. Last Year I fixed this issue using the solution quoted below.. but due to some other requirements for my auth system I had to build an Auth system customized for my application. If you've the time I'll suggest you take a break and get back on it later. Use the latest version as well. You never know until you give it all. Stay safe.
I got the same issue but got it fixed by put a forward slash in front of my urls
redirect: { login: '/public/login/', home: '/', logout: '/public/login/' }
instead ofredirect: { login: '/public/login', home: '/', logout: '/public/login' }
N.B: Notice the forward slash.
@donmb1
I came up with this which seems to work as I would have expected the redirects to work out of the box.
export default function ({ app }) { const oldLogout = app.$auth.logout.bind(app.$auth) const oldLogin = app.$auth.login.bind(app.$auth) app.$auth.logout = (...args) => { const _ = oldLogout(...args) _.then(() => app.$auth.redirect('logout')) return _ } app.$auth.login = (...args) => { // sometimes doesn't work when the user tries to get to the admin page // before being logged in. const _ = oldLogin(...args) _.then(() => { app.$auth.redirect('home') }) return _ } }
Worked for me
see https://github.com/nuxt-community/auth-module/issues/205#issuecomment-424385896
YES Finally
just remove auth: false
from your login.vue
export default {
components: {},
data() {
return {
login: {
username: '',
password: '',
},
}
},
// auth: false, <========================
methods: {
async userLogin() {
...
...
...
They seem to be moving to nuxt 3.0 though. I think maybe we should abandon this implementation next few months, Link to the new docs: https://dev.auth.nuxtjs.org/guide
I ended up building my own auth. As simple as fetching jwt token, writing to a localStorage and making a top-level request which decides if I am logged in or not.
If you're not using http only cookies for auth on the web, you're vulnerable to xss. Does not matter if u save the token in localstorage, memory or nom-http only cookies.
The only way is to have a server http only cookie with the session information. This requires the api and app to be in the same tld, but it's mostly the case anyway.
I had the same issues and fixed it the following way:
May people suggested setting propertyName: false
as @AllanPinheiroDeLima suggested:
endpoints: {
login: { url: '/api/login', method: 'post' },
logout: { url: '/api/logout', method: 'post' },
user: { url: '/api/me', method: 'get', propertyName: false },
},
However, seems this did nothing for me, the user was still undefined in vuex (remember to activate vuex by adding index.js in stores folder)
what worked for me was to use the user object and set property to false. This is probably the new way to do the suggestion @AllanPinheiroDeLima suggested.
local: {
endpoints: {
login: { url: '/api/login', method: 'post' },
logout: { url: '/api/logout', method: 'post' },
user: { url: '/api/me', method: 'get' },
},
user: {
property: false, // <---
},
token: {
property: 'access_token',
required: true,
type: 'Bearer',
},
},
This is kind of weird... my redirect config was like this:
redirect: {
login: '/login',
logout: '/login',
home: '/',
callback: '/'
}
And my problem was that when users came to the page, the stayed (not logged in) in the /
page, they were not redirected to /login
. Once I removed the callback
redirect, it works like a charm.
My complete auth config is this:
auth: {
strategies: {
local: {
endpoints: {
login: {
url: '/auth/local',
method: 'post',
propertyName: 'jwt'
},
user: {
url: '/users/me',
method: 'get',
propertyName: false
},
}
}
},
redirect: {
login: '/login',
logout: '/login',
home: '/'
}
}
I have been struggling, for days now, with redirects not working after login or logout. My setup was simple. Started a new nuxt project (SSR/Universal, with Axios, PWA), added nuxt auth-next, set auth
as middleware for router in nuxt.config.js. pages/index.vue
is not accessible without login. Created pages/login.vue
and set auth: "guest"
to allow login page to open only when not logged in.
Following is my auth config in nuxt.config.js
auth: {
redirect: {
login: "/login",
logout: "/login",
home: "/"
},
watchLoggedIn: true,
strategies: {
local: {
token: {
property: "jwt"
},
user: {
property: false
},
endpoints: {
login: {
url: "auth/local",
method: "post"
},
user: {
url: "users/me",
method: "get"
},
logout: false
}
}
}
}
With this setup, when login using local strategy, after successful login redirection didn't work and I had to refresh the page for user to redirect to /
.
this.$auth
.loginWith("local", {
data: {
username: this.username,
password: this.password
}
})
.then(response => {
console.log(response);
})
.catch(error => {
console.log(error.response);
});
At this point, I am at the brink of pulling my hair out from my head in frustration. Then magic happens.
I created a store/index.js
with the following code:
export const state = () => ({});
export const mutations = {};
export const getters = {};
export const actions = {};
basically, just a blank store.
Run the app again, and voila, redirection starts to work! Login, logout, everything works.
Hope this helps someone!
Hi @KunalAggarwal! Thank you for reporting :) From now on users will be warned that Vuex Store is not activated #1195
Hello,
thanks a lot @KunalAggarwal for your analysis and method.
As the solution seems to activate the Vuex module, placing an empty JS file in store/
folder does the trick. No code needed, and redirections work.
https://nuxtjs.org/docs/2.x/directory-structure/store#activate-the-store Nuxt.js will look for the store directory. If it contains a file, that isn't a hidden file or a README.md file, then the store will be activated.
Thanks again !
I was hoping the auth-next
package would handle things more gracefully than its' predecessor, but this does not seem to be the case. However, I was able to get everything working well, and without throwing navigation guard errors. My primary objective was to redirect the user back to the guarded path (including parameters) after a successful login.
An overview of my routes, and the desired redirect behavior is as follows:
If the user IS NOT authenticated the following should occur:
/ => /login
/login (no redirect occurs)
/sign-up (no redirect occurs ; the user needs to be able to sign up if they do not have a user account)
/logout (no redirect occurs)
/home => /login
/guarded/path => /login
/another/guarded/path?with= parameters => /login?with= parameters (the ?with=parameters displaying on the login page looks silly, and can likely be removed using a custom auth plugin via $auth.onRedirect. I just have not done this, yet. I will update this comment if I do.)
If the user IS authenticated the following should occur:
/ => /home
/login => /home
/sign-up => /home
/logout (no redirect occurs)
/home (no redirect occurs)
/guarded/path (no redirect occurs)
/another/guarded/path?with= parameters (no redirect occurs)
My auth relevant nuxt.config.js
is as follows:
auth: {
redirect: {
// do not allow auth to automatically redirect to home. we will do this with our custom auth-redirect middleware.
home: false,
login: '/login',
logout: '/logout',
},
strategies: {
local: {
token: {
property: 'jwt',
global: true,
},
user: {
property: false,
autoFetch: false,
},
endpoints: {
login: { url: '/auth/local', method: 'post' },
logout: { url: '/auth/logout', method: 'post' },
user: { url: '/users/me', method: 'get' },
},
},
},
},
// enable auth globally. we want to guard everything by default, and override on a case-by-case basis.
router: {
middleware: ['auth'],
},
My custom middleware/auth-redirect.js
middleware is as follows:
export default function ({ $auth, redirect, route }) {
// if the user is not authenticated, and we are not on the login or sign up page then redirect to the login page.
if (!$auth.loggedIn && !['/login', '/sign-up'].includes(route.path)) {
return redirect('/login')
// if the user is authenticated, and we are not on the home page then redirect to the home page.
} else if ($auth.loggedIn && route.path !== '/home') {
return redirect('/home')
}
}
My /
auth relevant logic is as follows:
<script>
export default {
auth: false,
middleware: 'auth-redirect',
}
</script>
My /login
auth relevant logic is as follows:
<script>
export default {
beforeRouteEnter(from, to, next) {
// attempt to store the route full path (including parameters) so that we may redirect to it after a successful login.
next((vm) => vm.setRedirectUrl(to))
},
auth: false,
middleware: 'auth-redirect',
data() {
return {
redirectUrl: null,
}
},
methods: {
setRedirectUrl(toRoute) {
// only store the route full path (including parameters) if the path of the route does not match one of the following. we do not want to redirect a successful login back to any of the following pages.
if (!['/', '/login', '/logout', '/sign-up'].includes(toRoute.path)) {
this.redirectUrl = toRoute.fullPath
}
},
async signinUser(userInfo) {
const userData = {
/* credentials go here */
}
try {
const response = await this.$auth.loginWith('local', { data: userData })
await this.$auth.setUserToken(response.data.jwt)
// if a redirect URL is set then redirect to the URL.
if (this.redirectUrl) {
this.$router.push(this.redirectUrl)
// if a redirect URL is not set then redirect to the home page.
} else {
this.$router.push('/home')
}
} catch (e) {
/* exception handling goes here */
}
},
},
}
</script>
My /sign-up
auth relevant logic is as follows:
<script>
export default {
auth: false,
middleware: 'auth-redirect',
}
</script>
My /logout
auth relevant logic is as follows:
<script>
export default {
auth: false,
created() {
if (this.$auth.loggedIn) {
this.$auth.logout()
}
},
mounted() {
this.$router.app.refresh()
},
}
</script>
Lastly, do not forget to initialize the Vuex store by at least creating an empty store/index.js
file. Redirects as well as many facets of auth seem to have issues when the Vuex store is not enabled.
My /guarded/paths
need no auth relevant logic as auth has been enabled globally in nuxt.config.js
.
I hope this helps. 🙏🏻
I had this problem. I'm using the refresh token scheme and what it worked for me was to, after calling the loginWith
method, write
await this.$auth.setUserToken(
response.data.token,
response.data.refreshToken
);
It might be redundant, but it's the fix I found. Hope it helps!
I have been struggling, for days now, with redirects not working after login or logout. My setup was simple. Started a new nuxt project (SSR/Universal, with Axios, PWA), added nuxt auth-next, set
auth
as middleware for router in nuxt.config.js.pages/index.vue
is not accessible without login. Createdpages/login.vue
and setauth: "guest"
to allow login page to open only when not logged in.Following is my auth config in nuxt.config.js
auth: { redirect: { login: "/login", logout: "/login", home: "/" }, watchLoggedIn: true, strategies: { local: { token: { property: "jwt" }, user: { property: false }, endpoints: { login: { url: "auth/local", method: "post" }, user: { url: "users/me", method: "get" }, logout: false } } } }
With this setup, when login using local strategy, after successful login redirection didn't work and I had to refresh the page for user to redirect to
/
.this.$auth .loginWith("local", { data: { username: this.username, password: this.password } }) .then(response => { console.log(response); }) .catch(error => { console.log(error.response); });
At this point, I am at the brink of pulling my hair out from my head in frustration. Then magic happens.
I created a
store/index.js
with the following code:export const state = () => ({}); export const mutations = {}; export const getters = {}; export const actions = {};
basically, just a blank store.
Run the app again, and voila, redirection starts to work! Login, logout, everything works.
Hope this helps someone!
It's work ! Thank you so much !
window.location.reload()
as simple solution and it was the only one that worked for me,
based on @vencho-mdp answer I believe that my problem happened because I am using "user: false" so my user object is {} and maybe this is the reason if someone from the development team interested in fixing this issue.
My problem now is that the pwa is freezing for some reason ig because of the redirection but am gonna search for that somewhere else
Edit: I found the problem with pwa, it was the same solution that I've suggested, so if you're planing to run pwa you can use plain javascript redirect with:
location.href = '/
location.href = '/login
in the promise of login and logout methods
Edit 2: pwa is freezing on production server even tho it worked on production on local host still debugging it
In my case issue was around cookie: false
, setting it to true
did the trick. I also noticed that using just localStorage has influence at watching loggedIn
prop. Without cookies I solved the problem manually redirecting after login with $router.push
and manual redirecting in mounted
on 'guest' routes if loggedIn: true
, but reloading page on a protected route redirects me to login page, and then to 'home'. Decided to keep cookies true :)
My issue fixed by set the auth: 'guest'
in login.vue and everything works.
@NoahCardoza solution is worked for me. Thx!
Version v4.5.1
Reproduction link https://github.com/nuxt-community/auth-module
Configuration
Action to login :
Action to logout : await this.$auth.logout();
Steps to reproduce I use local strategy with a token. After the token expires if i reload the page, the user is logged out because i have resetOnError=True. I'm redirect to my signin page. Then i try to reconnect, i get new token and when i check into VueX, i got this result :
But i'm not redirect to home page ... If i refresh, i'm connected into the home page.
Where i'm doing wrong ? Thanks for your answers.
Regards,