登录与退出功能-保存token和设置token过期时间过期重新到登录页面

Vue项目登录与退出功能-保存token和页面权限控制,设置token过期时间过期重新到登录页面,本地保存有token就直接不用输入账号密码跳转到首页

做vue后台管理系统的项目的过程中有个登录退出的业务逻辑:

  • (1)发起登录请求之前做个对账号密码表单的合法性进行验证规则
  • (2)登录的时候发起请求获取token
  • (3)将token保存到本地
  • (4)路由导航守卫:设置token的过期时间,如果过期了就重新导登录页面,如果用户在token还没有过期的时候打开了登录页面就直接跳转到首页

其实我们在登录成功之后,需要完成以下内容,来保持登录效果以及跳转登录首页:
1、将登录成功后的token,保存到客户端的sessionStorage中
(1) 项目中除了登录login组件接口,其他的组件页面必须在登录后才能访问
(2) token只应在当前网站打开期间生效,所以将token保存在sessionStotage中。
2、通过编程式导航this.$router.push('/home') 跳转到后台主页,路由地址是/home。

上面是对表单输入内容的合法性的验证规则。

下一步是主题内容....

login.vue

code
login() {
      this.$refs.loginFormRef.validate(async valid => {
        if (!valid) return
        const { data: res } = await this.$http.post('login', this.loginForm) /* 加await返回的是数据 不加返回promise 而返回的数据里面只有data才是api返回的数据 其他的都是axios的 解构并重命名即data重命名为res */
        if (res.meta.status !== 200)  return this.$message.error('登录失败!')
        this.$message.success('登录成功')
        // 登录成功后:
        // 1. 将登录成功之后的 token,保存到客户端的 sessionStorage 中 之后的网络请求中要拿这个token放入请求头中
        //   1.1 项目中除了登录之外的其他API接口,必须在登录之后才能访问 token就是登录令牌 
        //   1.2 token 只应在当前网站打开期间生效,所以将 token 保存在 sessionStorage 中(不是localstorage)
           window.sessionStorage.setItem('token',res.data.token)
           this.$router.push('/home')
        // 2. 通过编程式导航跳转到后台主页,路由地址是 /home 但是如果没有拿到token而直接输入地址也不应该跳转 此时要用导航守卫 如果要跳转的是登录页面则直接放行 如果跳转的是其他页面则要判断是否携带token 导航守卫写在router.js里面
        // this.$router.push('/home')
      })

    },

因为登录成功之后,需要跳转到后台首页,所以使用$router的push进行路由跳转 ,路由地址是“/home”

由于我们的Home页面是需要在登录成功之后才可以进行访问的,所以登录之前我们要控制用户无法访问该页面,如何做呢?

  •   除了login请求接口,其他都需要授权,才能正常请求数据,所以axios请求拦截器添加token,保证获取数据的权限
      里面有 headers 属性,手动保存在session本地,把这个令牌给token保存下来
      必须是 return config

main.js 代码:

code
 // 添加请求拦截器
// 拦截器的第一部分,第二部分在router index.js里面
axios.interceptors.request.use(function(config) {
  // 在发送请求之前做些什么
  // 判断是否存在token,如果存在将每个页面header添加token
  if (window.localStorage.getItem("token")) {
    config.headers.common['Access-Token'] = window.localStorage.getItem("token");
  }
  return config
})

我们要“路由导航守卫”来控制访问权限。如果用户没有登录,但是直接通过URL访问特定页面,需要重新导航到登录页面。router的beforeEach方法就是“路由导航守卫”,我们可以遍历router的所有路由地址,并可以设置跳转的动作。思路很简单,如果当前访问页面是登录页面,就正常跳转,如果不是,就检测是不是登录状态(token是否为空),如果不是,就跳转到登录页面,如果是就正常跳转。
我们在路由规则文件/router/index.js下,编写“挂载路由导航守卫”的逻辑:

router/index.js

code
 // 挂载路由导航守卫
router.beforeEach((to, from, next) => {
   // to 将要访问的路径
   // from 代表从哪个路径跳转而来
   // next 是一个函数,表示放行
   //     next()  放行    next('/login')  强制跳转

   if (to.path === '/login') return next()
   // 其他页面则要有token才能放行 之后的网络请求中要拿这个token放入请求头中
   const tokenStr = window.sessionStorage.getItem('token')
   if (!tokenStr) return next('/login') /* 没有用else if */
   next()
})

export default router /* 因为要挂载导航守卫 所以不能实时导出 */

其实上面的是比较常见的方法。还有一种是最完整的写法(token设置期限,token过期让客户重新登录等功能):

  • // 添加请求拦截器 // 拦截器的第二部分,第一部分在main.js里面
  • // 获取存储token的开始时间
  • // 后台给出的token有效时间,一个星期 单位 是秒
  • // 我们自己定义6天过期,让用户重新登录一下, 用户总不可能在一个页面挂机一天吧
  • // 当前时间 // 如果大于说明是token过期了
  • // 如果token过期了
  • // 如果token没有过期,又是选择了登录页面就直接重定向到首页,不需要重新输入账户密码

code
// 别忘了导入对应的依赖库----
//导入element提示语的组件
// 添加请求拦截器
// 拦截器的第二部分,第一部分在main.js里面
router.beforeEach((to, from, next) => {
 
  // 获取存储localStorage的token
  let token = window.localStorage.getItem('token')
  // 获取存储token的开始时间
  const tokenStartTime = window.localStorage.getItem('tokenStartTime')
  // 后台给出的token有效时间,一个星期 单位 是秒
  // 我们自己定义6天过期,让用户重新登录一下, 用户总不可能在一个页面挂机一天吧
  const timeOver = 6 * 24 * 3600 * 1000
  // 当前时间
  let date = new Date().getTime()
  // 如果大于说明是token过期了
  if(date - tokenStartTime > timeOver) {
     token = null
  }
  // 如果token过期了
  if (!token) {
    if (to.path == '/login') return next()
    // 注意要import element的Message组件
    Message.error("登录状态过期,请重新登录")
    return next('/login')
    // 如果token没有过期,又是选择了登录页面就直接重定向到首页,不需要重新输入账户密码
  } else if (to.path == '/login') {
    return next('/home')
  }
  next()
 
})
export default router

 

posted @ 2022-10-27 17:36  Mahmud(مەھمۇد)  阅读(1550)  评论(3编辑  收藏  举报