登录过期逻辑
现在普遍的登录权限校验方式是JWT (json web token),当登录成功时,前端页面会获得一个 token ,每个 token 都设置了过期时间,通过解析 token 即可判断出 token 是否过期。
token 过期,即登录过期。
核心技术
前端项目安装依赖 jsonwebtoken
和 dayjs
cnpm i -S jsonwebtoken cnpm i -S dayjs
src\router\index.js 中使用它们
import jwt from "jsonwebtoken"; import moment from "dayjs";
解析token
const payload = jwt.decode(token);
判断token是否过期
moment().isAfter(moment(payload.exp * 1000))
- moment() 即当前时间
- moment(payload.exp * 1000) 是token的过期时间
- isAfter() 用于判断当前时间是否晚于token的过期时间
完整代码范例
src\router\index.js
import Vue from "vue"; import VueRouter from "vue-router"; import store from "@/store"; import { store_State_init } from "@/store"; import jwt from "jsonwebtoken"; import moment from "dayjs"; import { Message } from "element-ui"; Vue.use(VueRouter); const routes = [ { path: "/", redirect: "/index/content" }, { path: "/index", component: (resolve) => require(["@/views/index/index.vue"], resolve), children: [ { path: "content", name: "首页的内容(首页中的首页)", component: (resolve) => require(["@/views/index/content.vue"], resolve), }, { path: "members", name: "成员", component: (resolve) => require(["@/views/members/index.vue"], resolve), }, // 博客 { path: "blog", meta: { requiresAuth: true }, component: (resolve) => require(["@/views/blog/index.vue"], resolve), }, { path: "*", component: (resolve) => require(["@/views/otherPages/404.vue"], resolve), }, ], }, // 注册 { path: "/register", component: (resolve) => require(["@/views/register/index.vue"], resolve), }, // 登录 { path: "/login", component: (resolve) => require(["@/views/login/index.vue"], resolve), }, // 作品 { path: "/index/works", component: (resolve) => require(["@/views/works/index.vue"], resolve), }, // 重置密码 { path: "/resetPassword", component: (resolve) => require(["@/views/resetPassword/index.vue"], resolve), }, // 用户中心 { path: "/userCenter", meta: { requiresAuth: true }, component: (resolve) => require(["@/views/userCenter/index.vue"], resolve), }, // 404 表示请求的页面不存在、已被删除或无法访问 { path: "/404", component: (resolve) => require(["@/views/otherPages/404.vue"], resolve), }, // 未匹配到的路由,重定向到 /404 { path: "*", redirect: "/404" }, ]; const router = new VueRouter({ routes, }); // 全局路由守卫 router.beforeEach((to, from, next) => { const token = store.state.token; if (token) { const payload = jwt.decode(token); // token过期 —— 当前时间超过token的过期时间 if (moment().isAfter(moment(payload.exp * 1000))) { sessionStorage.clear(); // 重置 vuex store.replaceState(store_State_init); Message({ offset: 150, message: "登录已过期!", type: "warning", }); } } // 需鉴权的路由—— 判断路由的meta元数据中,是否requiresAuth为true if (to.matched.some((record) => record.meta.requiresAuth)) { // 判断用户是否已登录 if (store.state.isLogin) { // 已登录,则跳转到目标路由(需要用户登录的页面) next(); } else { // 未登录,跳转到登录页 next("/login"); } } else { // 公共页面,直接跳转到目标路由 next(); } }); export default router;