Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Not redirecting after login when going directly on the route #134

Closed
mathieutu opened this issue Apr 11, 2018 · 56 comments · Fixed by #360
Closed

Not redirecting after login when going directly on the route #134

mathieutu opened this issue Apr 11, 2018 · 56 comments · Fixed by #360
Labels

Comments

@mathieutu
Copy link
Contributor

Version

v4.1.0

Reproduction link

https://nuxt-auth.herokuapp.com/secure

Steps to reproduce

Hi,
When accessing directly on a secured page, the redirect key is not set in the state, and there is not redirection after login.
This is visible in the demo: access directly this page without be logged, and you will not have the $auth.$state.redirect message: https://nuxt-auth.herokuapp.com/secure

What is expected ?

Screen Shot 2018-04-11 at 11.19.27.png

And redirection after login

What is actually happening?

Screen Shot 2018-04-11 at 11.19.36.png

And no redirection after login.

Additional comments?

Thanks!

This bug report is available on Nuxt.js community (#c100)
@ghost ghost added the cmty:bug-report label Apr 11, 2018
@pi0 pi0 added the bug label Apr 11, 2018
@stevepop
Copy link

stevepop commented May 3, 2018

Hi,

I am having the same issue myself on a project I am currently working on. When an un-authenticated user visits /member/profile, the user is redirected to the login page. After logging in, they are not redirected to the intended page but to the normal link redirect from login.

I see that this issue was raised since 22 days ago and not responded to. Is there a work-around I can implement before this issue is resolved?

Thanks!

@Lahori-Jawan
Copy link

I raised this issue on nuxt community but no one responded. @pi0 would you shed some light on this issue?

@Lahori-Jawan
Copy link

After failing to find any easy/reliable solution I came up with this one:
login.vue

methods: {
      login () {
	localStorage.setItem('redirect', this.$route.path)
	this.$auth.loginWith('google')
      }
}

and then in callback/redirect route
callback.vue

export default {
	mounted () {
		this.$router.push(localStorage.getItem('redirect'))
	}
}

Although everything works just fine but after redirecting to desired link it is redirected back to home page which i don't understand why.

@stevepop
Copy link

@Lahori-Jawan,The problem with relying on LocalStorage is that it is client side which can change at any point in time.
I am not so sure this is the best way to deal with this but if it works for you, it may be a temporary work-around

@Lahori-Jawan
Copy link

yeah, for now I am just looking for a work around but the problem is that after redirecting to the page it redirects back to homepage, can you guess Why @stevepop ?

@SnooHD
Copy link
Contributor

SnooHD commented May 14, 2018

@Lahori-Jawan I think this happens because the loggedIn watcher is still triggered, redirecting you to the login redirect option.

It is surely possible to prevent this through a custom middleware where you set store.auth.redirect
Because the watcher redirects you to this value.

But i think the solution using a cookie or the solution @belak came up with using a query would be better.

@Lahori-Jawan
Copy link

@SnooHD Thank you for the input. Actually I am avoiding those solutions for now bec. they both seem pretty daunting for this simple scenario. Could you give me a bit more insight to your suggestion? do you mean like store.auth.redirect = false ?

@SnooHD
Copy link
Contributor

SnooHD commented May 14, 2018

@Lahori-Jawan store.auth.redirect = '/path-you-want-to-redirect-to' so in your case localStorage.getItem('redirect').

Obviously because its a vuex store property, you will have to use a commit.

@belak
Copy link

belak commented May 15, 2018

It obviously needs to be cleaned up, but I think the query param is better because it allows you to handle multiple redirects... like if you open a browser that's been closed for a while and a number of tabs open on the same site - with the localStorage method, you can only track one of those (as it's stored in a single key). Once a user logs in to one tab, they lose the redirects on all the other pages, but with query params, they can still be redirected.

Unfortunately, while it's better for that situation, it's a bit less flexible. It would be nice to maintain state between redirects, but I feel like it would be a lot of complication for minimal benefit.

@remibeaufils
Copy link

Is someone working on a fix for this bug?

@SnooHD
Copy link
Contributor

SnooHD commented Jun 11, 2018

@nitescent If you truly want to solve this right now, there are 2 ways to do it until a better solution is integrated.
Both can be found here: #165

@zolotyx
Copy link

zolotyx commented Jul 27, 2018

Please, take a look at my workaround

Create plugins/auth.js file
Add plugins: ['~/plugins/auth.js'], to auth section of the nuxt.config.js
here is a content of the auth.js file: https://gist.github.com/zolotyx/b4e7fda234b3572fb7adaf11391f8eef

@remibeaufils
Copy link

Thanks @zolotyx, I'm using your solution now

@ribrewguy
Copy link

@zolotyx The workaround continually results in Cannot read property 'options' of undefined. I've added it to the plugins section of auth. Is there something I'm missing?

@joshink
Copy link

joshink commented Aug 9, 2018

@RediJedi not sure if you figured it out by now, but you need to add the plugin to the auth setting, not the global plugins:

auth: {
  ...
  plugins: ['~/plugins/auth.js']
}

@ribrewguy
Copy link

@joshink Thanks, but that still doesn't work. It is only in the auth block but I get

[1] Caught error: TypeError TypeError: Cannot read property 'options' of undefined
[1]     at Auth.redirect (src/plugins/auth.js:8:0)
[1]     at module.exports.__WEBPACK_IMPORTED_MODULE_0__middleware__.a.auth (.nuxt/auth/middleware.js:31:0)
[1]     at promisify (.nuxt/utils.js:203:0)
[1]     at middlewareSeries (.nuxt/utils.js:184:0)
[1]     at module.exports.__webpack_exports__.default (.nuxt/server.js:114:0)
[1]     at <anonymous>
[1]     at process._tickDomainCallback (internal/process/next_tick.js:228:7)

@ribrewguy
Copy link

@joshink Actually, it was my fault. I was rewriting the redirect function as an arrow function to make eslint happy. Not doing that got rid of the error, but the app still doesn't redirect to the path in the query string. Could be my fault...digging.

@joshink
Copy link

joshink commented Aug 10, 2018

@RediJedi Yeah, I think all that code actually does is pass the redirect to the login page for you. It was not redirecting automatically for me either. You should be able to do something like this in your login page's methods.

async handleLogin () {
  await this.$auth.login( { data } )
  this.$router.go(decodeURIComponent(this.$route.query.redirect || "/"))
}

Hope that helps!

@shawnlauzon
Copy link

The workaround provided by @zolotyx resolves the problem for me. As @SnooHD says, the problem is that when Vuex is used, the redirect is stored in Vuex but after the redirect, the store is lost and so it forgot where to redirect to.

The workarounds referenced in #165 may be "better" (I don't really know), but they seem to be more effort than the above workaround, and so I prefer the simpler workaround until something is integrated into the system itself.

@SnooHD
Copy link
Contributor

SnooHD commented Nov 8, 2018

@shawnlauzon
My solution uses cookies, @belak uses a query and @zolotyx's is using the localStorage.
I would say it hardly matters.

It's just that the localStorage will be cleared when the session ends (when tab / browser closes).
The other solutions should work for a new session as well.

@yaliv
Copy link

yaliv commented Nov 25, 2018

I have a related question here:
https://cmty.app/nuxt/auth-module/issues/c237

I think writing a Plugin is really boring.
There should be a simpler solution.

@hashinteractive
Copy link

Does anyone know if any of these options work with an Identity Provider/auth0 protocol?

@SnooHD or @zolotyx do either of you know if your solutions would work with an identity provider in which the user is redirected off the nuxt site to the identity provider for verification and brought back to the callback url? I have tried both solutions to no avail as the redirects are not working (even though they are stored as cookies in @SnooHD solution).

Any ideas on this would be greatly appreciated!

@andershagbard
Copy link

andershagbard commented Feb 11, 2019

I've ran into this issue as well. My mistake was having auth: false set on my login page. If you have it, just remove it.

<script>
export default {
  auth: false
}
</script>

@ghost
Copy link

ghost commented Feb 15, 2019

I've ran into this issue as well. My mistake was having auth: false set on my login page. If you have it, just remove it.

Thank you. This fixed my issue with the Auth Module.

@albanafmeti
Copy link

albanafmeti commented May 16, 2019

I've ran into this issue as well. My mistake was having auth: false set on my login page. If you have it, just remove it.

<script>
export default {
  auth: false
}
</script>

This is not working properly. It fixes the problem temporary.

@MathiasCiarlo
Somebody should merge that PR. This is a critical issue.
Thanks for the PR. Hope that's the solution.

@geeky-geek
Copy link

It affects us too :/
@MathiasCiarlo thanks for the PR!

@pi0
Copy link
Member

pi0 commented May 30, 2019

Should be fixed in v4.6.0. Sorry for this late update.

@pi0 pi0 closed this as completed May 30, 2019
@olivermaldonado
Copy link

Is it just me, or is anybody else still having this exact issue? Even after v4.6.0..

@guesskingf
Copy link

Still got this issue, can't set redirect in auth store after v4.6.0 @pi0

@lpeppe
Copy link

lpeppe commented Jul 1, 2019

Yes, same here...

@8bu
Copy link

8bu commented Jul 3, 2019

got the same issue here, tried many work arounds I found on this issue feedback but none of them worked.

@pi0
Copy link
Member

pi0 commented Jul 3, 2019

I wonder if newly reported issues are exactly the same. Please create new issue with reproduction code (or at least URL) + steps

@8bu
Copy link

8bu commented Jul 4, 2019

I just found out that redirect issue will be solved when disable vuex-persist plugin that I added before.

@8bu
Copy link

8bu commented Jul 11, 2019

Btw, the plugin will be conflict a little bit with some vuex persist plugin. Please update the doc to tell people do not include auth module when they use vuex-persist plugin or localStorage to store vuex state.

@AllanPinheiroDeLima
Copy link

AllanPinheiroDeLima commented Jul 18, 2019

I've answered in another issue, but I'll put here too:

The thing is that is seems that the nuxt auth plugin waits this property to be defined to redirect to home. 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'
    }
  }

@raquelriobo
Copy link

raquelriobo commented Jun 15, 2020

RETURNING TO THE REQUEST PAGE AFTER LOGIN

Build in a system for keeping track of what page was originally requested and redirect to it after a successful login can be done in 2 steps.

As @belak said:

The query param solution is better,

However, for me his solution didn’t work as I have problems when trying to import the helpers from the library. Nevertheless, there is a most simple solution:

  • Create an auth-guard middleware that saves the requested url and redirects to the login with such url saved in the query params.

    • Declare the middleware in the nuxt config and disable @nuxtjs/auth redirect option as it will be done in the new middleware.

      nuxt.config.js:

      router: {
      		middleware: ['auth-guard'],
      },
      auth: {
          vuex: { namespace: '_auth' },
          redirect: {
               login: false,
               logout: '/login',
               callback: false,
               home: false,
           },
           localStorage: false,
      },
      strategies: {
        local: {
          endpoints: {
            login: {
              url: '/auth/login',
              method: 'post',
              propertyName: 'access_token',
            },
            logout: {
              url: '/auth/logout',
              method: 'post',
            },
            user: {
              url: '/auth/me',
              method: 'get',
              propertyName: false,
            },
          },
        },
      }
    • When the route path is different than login save such path and redirect to it if the user is NOT logged in.

      middleware/auth-guard.js

      export default function({ $auth, route, redirect }) {
      if (route.path !== '/login') {
      	const REDIRECT_URL = '/login?redirect=' + route.path
      	if (!$auth.loggedIn) {
        		redirect(REDIRECT_URL)
      	}
       }
      }
  • Use the query params for redirect after a successful login to the saved path if exists.

pages/login.vue

  const handleSubmit = async () => {
      try {
        errorMsg.value = undefined
        await form.submit()
        let redirect_url = root.$route.query.redirect || '/dashboard'
        root.$router.push({
          path: redirect_url,
        })
      } catch (error) {
        errorMsg.value = t(`auth.login.error.${error.code}`)
      }
    }

@caroait
Copy link

caroait commented Jul 9, 2020

I was fighting with this error too and I solve it adding this line before redirect to the login

$auth.$storage.setUniversal('redirect', path)

@renztoygwapo
Copy link

Hi @caroait can you show me your code where did you put that ?

Thanks

@caroait
Copy link

caroait commented Jul 19, 2020

Hi @renztoygwapo I use it before do $auth.login()

@dpezzuoli
Copy link

dpezzuoli commented Aug 4, 2020

i resolve this add [strictMode: true] in vuex-persist.js plugin:

new VuexPersistence({ ... strictMode: true, ... }).plugin(store);

@Oscar2av
Copy link

Oscar2av commented Sep 2, 2020

I had a similar problem. I had to redirect the user depending on the Role (User or admin), so, the solution of just writing one common redirection did not work for me. I did the following, I have created a vue page called redirect.vue and there I wrote a middleware that checks the role of the user in order to redirect to the correct page (getting the users info from the vuex store), this solution may not be the best one but works. I hope this help someone!

redirect.vue (page):

<template>
  <div></div>
</template>

<script>
export default {
  middleware: 'redirect_middleware',
  data() {
    return {}
  }
}
</script>

redirect_middleware.js (middleware)

export default function({ store, redirect }) {
  if (
    store.state.auth.loggedIn &&
    (store.state.auth.user.role === 'user'
  ) {
    return redirect('/userspage')
  } else if (
    store.state.auth.loggedIn &&
    store.state.auth.user.role === 'admin'
  ) {
    return redirect('/adminpage')
  }
}

Note: For this to work, make sure that in the users table is a field called "role"

auth object inside nuxt.config.js

auth: {
  strategies: {
    local: {
      endpoints: {
        login: {
          url: 'api/auth/login',
          method: 'post',
          propertyName: 'token'
        },
        logout: {
          url: 'api/auth/logout',
          method: 'get'
        },
        user: {
          url: 'api/me',
          method: 'get',
          propertyName: 'data'
        }
      }
    }
  },
  redirect: {
    home: '/auth/redirect',
    login: '/auth/login',
    logout: '/'
  },
  fullPathRedirect: true
}

From Colombia to the world! :)

@yondifon
Copy link

RETURNING TO THE REQUEST PAGE AFTER LOGIN

Build in a system for keeping track of what page was originally requested and redirect to it after a successful login can be done in 2 steps.

As @belak said:

The query param solution is better,

However, for me his solution didn’t work as I have problems when trying to import the helpers from the library. Nevertheless, there is a most simple solution:

  • Create an auth-guard middleware that saves the requested url and redirects to the login with such url saved in the query params.

    • Declare the middleware in the nuxt config and disable @nuxtjs/auth redirect option as it will be done in the new middleware.
      nuxt.config.js:
      router: {
      		middleware: ['auth-guard'],
      },
      auth: {
          vuex: { namespace: '_auth' },
          redirect: {
               login: false,
               logout: '/login',
               callback: false,
               home: false,
           },
           localStorage: false,
      },
      strategies: {
        local: {
          endpoints: {
            login: {
              url: '/auth/login',
              method: 'post',
              propertyName: 'access_token',
            },
            logout: {
              url: '/auth/logout',
              method: 'post',
            },
            user: {
              url: '/auth/me',
              method: 'get',
              propertyName: false,
            },
          },
        },
      }
    • When the route path is different than login save such path and redirect to it if the user is NOT logged in.
      middleware/auth-guard.js
      export default function({ $auth, route, redirect }) {
      if (route.path !== '/login') {
      	const REDIRECT_URL = '/login?redirect=' + route.path
      	if (!$auth.loggedIn) {
        		redirect(REDIRECT_URL)
      	}
       }
      }
  • Use the query params for redirect after a successful login to the saved path if exists.

pages/login.vue

  const handleSubmit = async () => {
      try {
        errorMsg.value = undefined
        await form.submit()
        let redirect_url = root.$route.query.redirect || '/dashboard'
        root.$router.push({
          path: redirect_url,
        })
      } catch (error) {
        errorMsg.value = t(`auth.login.error.${error.code}`)
      }
    }

To make it dynamic. You can update the links to look like this.

export default function ({ $auth, route, redirect }: any) {
    if (route.path !== $auth.options.redirect.login) {
        if (!$auth.loggedIn) {
            redirect($auth.options.redirect.login, { redirect: route.path })
        }
    }
}

@OndraRehounek
Copy link

OndraRehounek commented May 16, 2021

I tried to follow the idea of @raquelriobo but it seemed to me little bit "too manual". But it gave me idea of this workaround since (maybe only in my case) there is the redirect path kept in localStorage (but redirect is not happening (just sometimes...).

I disabled home redirect in nuxt.config.js auth settings:

  auth: {
    redirect: {
      login: '/auth/login/',
      logout: '/auth/logout/',
      callback: false,
      home: false
    },
   ....

And then, when user tries to login I do redirect manually:

  // pages/auth/login.vue
  methods: {
    async login() {
      try {
        await this.$auth.loginWith('local', { data: { userName: this.userName, password: this.password } })
        this.$router.push(localStorage['auth.redirect'] ? { path: localStorage['auth.redirect'] } : { name: 'index' })
      } catch (e) {
        this.$toast.error(e.message)
      }
   }
   ....

So only manual localStorage['auth.redirect'] seems to be needed to solve (my) redirect issue but I am not sure if it will work for everyone since it is happening quite randomly in our app and might be just some async problem.

@KunalAggarwal
Copy link

Refer to #205 (comment) in case login logout redirection doesn't work for someone. I managed to get it working as mentioned in that comment. Might be helpful for someone.

@n4an
Copy link

n4an commented Oct 8, 2021

This nuxt auth module will be my final push to using react, on this new project. It just has so much inconsistences.

why I not start with next!!!!???
waste of time

@n4an
Copy link

n4an commented Oct 8, 2021

[Axios] Request error: TypeError: Cannot read property 'url' of undefined
at server.js:10192:46
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at async LocalScheme.logout (server.js:10453:7)

@gluktd
Copy link

gluktd commented Oct 15, 2021

i resolve this add [strictMode: true] in vuex-persist.js plugin:

new VuexPersistence({ ... strictMode: true, ... }).plugin(store);

That was the thing!

@juac08
Copy link

juac08 commented Oct 18, 2021

@RediJedi Yeah, I think all that code actually does is pass the redirect to the login page for you. It was not redirecting automatically for me either. You should be able to do something like this in your login page's methods.

async handleLogin () {
  await this.$auth.login( { data } )
  this.$router.go(decodeURIComponent(this.$route.query.redirect || "/"))
}

Hope that helps!

Store the redirect in local storage, if local storage have a the redirect then go to the spacific redirect otherwise /. after redirect clear local storage

@kon3ko
Copy link

kon3ko commented Feb 13, 2022

i resolve this add [strictMode: true] in vuex-persist.js plugin:

new VuexPersistence({ ... strictMode: true, ... }).plugin(store);

Thank a lot man!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet