Skip to content

how to make router redirect to login when the auth state is kept by store? #3

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

Closed
funkyLover opened this issue Mar 18, 2016 · 5 comments

Comments

@funkyLover
Copy link

I want store to keep the state of auth or user info, also keep auth state in cookie or localstorage.
when user open the page, try to get the auth from cookie or localstorage and make it into store.
and make router redirect to login when user not login or can not get auth locally.
should I do that within router.beforeEach? but how could I get the store.state.auth

any advice?

@funkyLover
Copy link
Author

I make some try like below

// router config
Vue.use(VueRouter)

var router = new VueRouter({
  saveScrollPosition: true,
  history: true
})

router.map({
  '/user/login': {
    component: Login
  },
  '/': {
    component: Layout,
    subRoutes: {
      '/index': {
        component: Index
      },
      '/hello': {
        component: Hello
      }
    }
  },
  '*': {
    component: NotFound
  }
})

export default router
//auth.js
import { LOGIN, LOGOUT } from '../mutation-types'

const state = {
  auth: null
}

const mutations = {
  [LOGIN] (state, data) {
    state.auth = data.auth
  },
  [LOGOUT] (state) {
    state.auth = null
  }
}

export default {
  state,
  mutations
}
// store.js
Vue.use(Vuex)
Vue.config.debug = true

const debug = process.env.NODE_ENV !== 'production'

export default new Vuex.Store({
  modules: {
    auth
  },
  strict: debug,
  middlewares: debug ? [createLogger()] : []
})
//main.js -> the entry
Vue.use(VueResource)
sync(store, router)

router.start(App, '#Entry')

and I make auth filter within App.vue

<template>
  <div id="YG_App">
    <h1>Hello App!</h1>
    <router-view></router-view>
  </div>
</template>

<script>
import store from './vuex/store'
export default {
  store,
  vuex: {
    getters: {
      auth: ({ auth }) => auth.auth,
      route: ({ route }) => route
    }
  },
  created () {
    if (!this.auth && this.route.path !== '/user/login') {
      store.dispatch('router/ROUTE_CHANGED', {path: '/user/login'})
    }
  }
}
</script>

and it work find..is that a good practice?

@jsiebach
Copy link

+1. Currently state doesn't appear to be available in this router hook. Would need to use a mixin of some kind on the component. I think the way you're doing it is fine, but that does require the component to load before it redirects back to the login page, so it isn't ideal

@jsiebach
Copy link

Hey I was able to get access to the store from inside this hook, but it wasn't pretty:

router.beforeEach((transition)=>{
    if(transition.to.auth){
        if(!transition.to.router.app.$store.state.auth.authorized){
            transition.abort()
            router.go({path:"/"})
        }
    }
    transition.next()
});

I can't however get access to call actions from within this hook, that's the next step... I would like to run an action and get a response before calling transition.abort() so I can check the server to see if the JWT token is valid.

@funkyLover
Copy link
Author

you are right,,component will be loaded before redirect..I think it is pretty cool can run action within the router hook. when use the router hook inside the component, also work fine, and look more reasonable

// login.vue
<script>
import { sessionLogin } from '../vuex/actions'
export default {
  vuex: {
    getters: {
      userInfo: ({ userInfo }) => userInfo
    },
    actions: {
      sessionLogin
    }
  },
  route: {
    activate (transition) {
      let {session_id} = this.userInfo
      if (!session_id) {
         // check session from server
         this.sessionLogin({
          admin_session: {
            admin_session_id: session_id
          }
        }).then((res) => {
          // login success, get to index
          return transition.redirect('/')
        }, (err) => {
          // fail to check the session, get to login
          return transition.next()    
        })
      } else {
        // no session or other auth info, get to login 
        return transition.next()
      }
    }
  }
}
</script>

but the same problem, component is loaded before activate hook, otherwise, get an expected error when replace activate with canActivate hook

@yyx990803
Copy link
Member

In the next breaking release of vue-router, canActivate will most likely be deprecated, so everything should just happen in activated, which is likely to be renamed to onEnter for clarity.

It does mean that when the hook is called, the component would have already been created. However we will likely introduce some optimization so that by the time the hook is called, the component is in "instantiated" state, but not yet "compiled", so that it's going to be relatively cheap.

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

No branches or pull requests

3 participants