登录页成功之后,跳转进入主页
tip: 这里dispatch是异步的,需要加async await
async doLogin() {
try {
await this.$store.dispatch('user/userLogin', this.loginForm)
this.$router.push('/')
} catch (err) {
alert('用户登录,失败')
console.log('用户登录,失败', err)
}
},
路由守卫的格式
路由守卫中一定执行
next
- to:要去哪个页面
- from:从哪里来
- next:它是一个函数。
1. 如果直接放行 next()
2. 如果要跳到其它页 next(其它页)
router.beforeEach((to, from, next) => {
console.log(to, from)
next()
})
路由导航守卫-实现两个跳转限制
白名单:那些不需要token就可以直接访问的页面
- 登陆用户不能再次回到login
- 没有登陆就不能访问除login之外的其它页
- router.beforeEach(回调(三个参数:to,from,next)
router.beforeEach((to, from, next) => {
console.log(to)
// 获取token
console.log('全局前置路由守卫 获取token ', store.getters.token)
// 有token,已经登陆了
if (store.getters.token) {
// 如果要去login,则直接跳到主页
if (to.path === '/login') {
console.log('已经登陆了,就不能再访问login,应该去主页')
next('/')
} else {
// 有token,要去的不是login,就直接放行
next()
}
} else {
// 没有token,
// 要去的页面在白名单中,放行
// to.path在whiteList数组中
if (whiteList.includes(to.path)) {
next()
} else {
console.log('没有token,就不能访问白名单之外的页面,应该去登陆')
next('/login')
}
}
})
includes: 在一个数组里找一个数据 ,如果找到为true,找不到为false **
这里的图标我们使用了 svg,设置颜色需要使用svg标签的fill属性
调用action
时机分析:
- 因为依赖token去获取用户数据 所以必须要在获取了token之后才能调用这个action函数
- 因为跳转到首页后就要显示数据了,所以要求我们在跳转进入首页之前就提前拿回用户个人数据
确保两件事情:
- token已经存在
- 成功获取会数据之后才能进行跳转(同步)
`src/permission.js`
// 引入路由配置
import router from './router'
// 引入vuex,因为要获取其中token
import store from './store'
// 引入一份进度条插件
import NProgress from 'nprogress'
import 'nprogress/nprogress.css' // 引入进度条样式
// 白名单: 不需要token就可以直接访问的页面
const whiteList = ['/login'] // no redirect whitelist
// 全局前置路由守卫
// to:要去哪个页面
// from:从哪里来
// next:它是一个函数。
// 如果直接放行 next()
// 如果要跳到其它页 next(其它页)
router.beforeEach(async(to, from, next) => {
NProgress.start() // 启动进度条
// 获取token
console.log('全局前置路由守卫 获取token ', store.getters.token)
// 有token,已经登陆了
if (store.getters.token) {
// 如果要去login,则直接跳到主页
if (to.path === '/login') {
console.log('已经登陆了,就不能再访问login,应该去主页')
next('/')
} else {
// 有token,要去的不是login,就直接放行
// 派发action来发aja进一步获取用户信息
// 由于dispatch过程是异步的,要加await,才能保证是先获取用户信息,再跳转的
await store.dispatch('user/getUserInfo')
next()
}
} else {
// 没有token,
// 要去的页面在白名单中,放行
// to.path在whiteList数组中
if (whiteList.includes(to.path)) {
next()
} else {
console.log('没有token,就不能访问白名单之外的页面,应该去登陆')
next('/login')
}
}
})
router.afterEach(() => {
// 结束进度条
NProgress.done()
})
Token失效处理
后端:收到用户访问某个接口时,检查当前token是否失效,如果token已经失效,返给前端一个约定好的状态码 10002
前端:在响应拦截器中,分析接口的返回值,如果状态码为10002, 则进行token失效操作由于页面跳转要用到路由,先引入路由:
import router from '@/router'
error => {
if (error.response && error.response.data && error.response.data.code === 10002) {
Message({
message: '请重新登陆',
type: 'error',
duration: 5 * 1000
})
// token失效了
// 1. 手动执行logout, 删除token
store.dispatch('user/logout')
// 2. 回到登陆页
router.push('/login')
} else {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
}
return Promise.reject(error)
}
- 以上方案为后端主导的方案,前端只需要拿到错误码做业务处理即可,此方案也是常用且安全的最优方案 小提示:模拟token失效,找到Application面板 找到cookies把 token数据右键之后删除几位 重新刷新页面