vue项目中的登录鉴权
Posted 水香木鱼
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue项目中的登录鉴权相关的知识,希望对你有一定的参考价值。
Login 组件
登录成功后做本地存储和store存储,并进行跳转。
Login.vue关键代码:
async handleLogin(e) { e.preventDefault(); let parmas = { username: this.model.username, passwold: this.model.passwold }; const res = await this.$http.get("/api/login", parmas); const { code, token, massage } = res.data; //code=='0'表示登录成功,进行本地存储和store存储 并进行跳转。 //else 弹出错误提示 if (code == "0") { this.$store.commit("setToken", res.data.token); localStorage.setItem("token", token); //如果是由需要鉴权的页面跳转到登录页面 则redirect= this.$route.query.redirect,如果是直接点击登录跳转到登录页面,则redirect= '/' const redirect = this.$route.query.redirect || "/"; this.$router.push(redirect); } else { const toast = this.$createToast({ time: 2000, txt: massage || "登录失败", type: "error" }); toast.show(); } }
store
在Login组件里登录时token做了数据持久化处理,防止页面刷新丢失token。给store里的token赋初值的时候要取
store.js关键代码:
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: { //token数据持久化,防止页面刷新丢失 token: localStorage.getItem('token') || '' }, mutations: { setToken(state, token) { state.token = token } }, actions: { }, getters: { //根据token是否存在,设置计算属性isLogin isLogin(state) { return !!state.token } } })
router
routes[]里用 mate.auth来标识是否需要鉴权。router.beforeEach做个全局路由守卫,根据是否需要鉴权以及是否已经登录来进行不同操作。
router.js代码:
import Vue from 'vue' import Router from 'vue-router' import Home from './views/Home.vue' import Login from './views/Login.vue'; import store from './store'; Vue.use(Router) const router = new Router({ mode: 'history', base: process.env.BASE_URL, routes: [ { path: '/', name: 'home', component: Home }, { path: '/login', name: 'login', component: Login }, { path: '/about', name: 'about', meta: { auth: true },//about需要做登录鉴权 component: () => import(/* webpackChunkName: "about" */ './views/About.vue') } ] }) router.beforeEach((to, from, next) => { //to.meta.auth 表示需要做登录健全 //不需要的 可以直接next if (to.meta.auth) { //store.state.token 表示已经登录 可以直接next //没有登录 跳转到/login 并携带参数redirect 方便登录后直接跳转到to.path if (store.state.token) { next(); } else { next({ path: '/login', query: { redirect: to.path } }) } } else { next(); } }) export default router;
axios拦截
axios.interceptors.request.use拦截axios所有http请求,如果存在token,则放入请求头。axios.interceptors.response.use拦截的axios的响应,如果token以及失效,则清除本地缓存和store存储并跳转到登录页面。
http-interceptors.js代码:
import axios from "axios"; import store from "./store"; import router from "./router"; // 拦截axios所有http请求,预先放入token请求头 axios.interceptors.request.use(config => { if (store.state.token) { // 若存在token,则放入请求头 config.headers.token = store.state.token; } return config; }); // 响应拦截器,提前预处理响应 axios.interceptors.response.use( response => { // 如果code是-1,说明用户已注销或者token已过期 // 此时需要重新登录,并且还要清除本地缓存信息和store数据 if (response.status == 200) { const data = response.data; if (data.code == -1) { logoutFun() } } return response; }, err => { if (err.response.status === 401) { // 未授权 logoutFun() } } ); function logoutFun() { // 清空本地缓存的token和store里的token store.commit("setToken", ""); localStorage.removeItem("token"); // 跳转至登录页,并携带用户退出时或token失效时的页面路由,方便登录后直接跳转到此页面。 router.push({ path: "/login", query: { redirect: router.currentRoute.path } }); }
服务端中间件
服务端也需要做请求处理的中间件。如果请求不是req.path不是'/api/login'并且没有携带token,则返回错误状态码401。
vue.config.js关键代码:
app.use((req, res, next) => { //只对api开头的请求做拦截处理 if (/^\\/api/.test(req.path)) { if (req.path == '/api/login' || req.headers.token) { next(); } else { //设置错误状态码为401 res.sendStatus('401') next(); } } else { next(); } })
以上是关于vue项目中的登录鉴权的主要内容,如果未能解决你的问题,请参考以下文章