1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > Vue+vue-router+路由守卫实现路由鉴权功能

Vue+vue-router+路由守卫实现路由鉴权功能

时间:2019-06-30 09:33:46

相关推荐

Vue+vue-router+路由守卫实现路由鉴权功能

路由鉴权功能是Vue+vue-router框架中常见的功能之一,也是前端安全性的一个重要方面。这里提供一个基于Vue+vue-router的路由鉴权实战

安装依赖

首先,在Vue项目中安装所需的依赖。安装Vue、vue-router以及axios等依赖,创建一个新的Vue实例。

npm install vue vue-router axios --save

设置路由和路由守卫

在路由设置中,我们将路由拆分为两类,需要进行鉴权的路由和不需要进行鉴权的路由。需要进行鉴权的路由需要在路由元信息中添加requiresAuth: true属性。

在我们设置路由时,需要引入路由守卫。这里我们使用router.beforeEach守卫,在进入每个路由之前进行鉴权验证。

// main.js

import Vue from 'vue';import App from './App.vue';import router from './router';Vue.config.productionTip = false;router.beforeEach((to, from, next) => {if (to.matched.some(record => record.meta.requiresAuth)) {// 判断该路由是否需要进行鉴权// 获取tokenconst token = localStorage.getItem('token');if (!token) {// token不存在,则跳转到登录页next('/login');} else {// token存在,则进行下一步路由next();}} else {next(); // 不需要进行鉴权,直接进行下一步路由}});new Vue({router,render: h => h(App),}).$mount('#app');

实现登录页

登录页中需要对用户的信息进行验证,并在验证通过后获取返回的token。这里我们使用axios库来发送登录请求。

<template><div class="login-page"><h2>Login</h2><div><label>Username:</label><input type="text" v-model="username"></div><div><label>Password:</label><input type="password" v-model="password"></div><button @click="login">Login</button></div></template><script>import axios from 'axios';export default {data() {return {username: '',password: '',};},methods: {async login() {const {data } = await axios.post('/api/login', {username: this.username, password: this.password });localStorage.setItem('token', data.token); // 将token存入localStorage中this.$router.push('/');},},};</script><style scoped>.login-page {width: 400px;margin: 0 auto;padding: 20px;background-color: #f8f8f8;border: 1px solid #ccc;}input {padding: 8px;border: 1px solid #ccc;border-radius: 4px;margin-bottom: 10px;}button {padding: 10px 20px;background-color: #007aff;color: white;border: none;border-radius: 4px;cursor: pointer;}</style>

设置需要鉴权的路由

在路由设置中,我们为需要鉴权的路由添加requiresAuth元信息。这里我们设定/profile路由需要进行权限验证。

// router.js

import Vue from 'vue';import VueRouter from 'vue-router';import Home from './views/Home.vue';import Login from './views/Login.vue';import Profile from './views/Profile.vue';Vue.use(VueRouter);const routes = [{path: '/',name: 'home',component: Home,},{path: '/login',name: 'login',component: Login,},{path: '/profile',name: 'profile',component: Profile,meta: {requiresAuth: true,},},];const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes,});export default router;

实现需要鉴权的页面

最后,在需要鉴权的页面中,我们可以使用beforeRouteEnter守卫来在进入页面前获取用户信息。这里我们使用axios库获取用户信息。

<template><div class="profile-page"><h2>Profile</h2><div><label>Username:</label><span>{{username }}</span></div><div><label>Email:</label><span>{{email }}</span></div></div></template><script>import axios from 'axios';export default {data() {return {username: '',email: '',};},beforeRouteEnter(to, from, next) {axios.get('/api/userinfo').then(({data }) => {next(vm => {vm.username = data.username;vm.email = data.email;});}).catch(() => {next('/');});},};</script><style scoped>.profile-page {width: 400px;margin: 0 auto;padding: 20px;background-color: #f8f8f8;border: 1px solid #ccc;}label {font-weight: bold;}span {margin-left: 10px;}</style>

上述代码中,在进入页面之前,我们使用axios发送请求获取用户信息。如果获取失败,则跳转到首页。如果请求成功,则将用户信息存入Vue实例中,并使用next将其传递给组件。在组件中,我们可以直接使用username和email属性渲染页面。

完整的代码如下:

// main.js

import Vue from 'vue';import App from './App.vue';import router from './router';Vue.config.productionTip = false;router.beforeEach((to, from, next) => {if (to.matched.some(record => record.meta.requiresAuth)) {// 判断该路由是否需要进行鉴权// 获取tokenconst token = localStorage.getItem('token');if (!token) {// token不存在,则跳转到登录页next('/login');} else {// token存在,则进行下一步路由next();}} else {next(); // 不需要进行鉴权,直接进行下一步路由}});new Vue({router,render: h => h(App),}).$mount('#app');

// router.js

import Vue from 'vue';import VueRouter from 'vue-router';import Home from './views/Home.vue';import Login from './views/Login.vue';import Profile from './views/Profile.vue';Vue.use(VueRouter);const routes = [{path: '/',name: 'home',component: Home,},{path: '/login',name: 'login',component: Login,},{path: '/profile',name: 'profile',component: Profile,meta: {requiresAuth: true,},},];const router = new VueRouter({mode: 'history',base: process.env.BASE_URL,routes,});export default router;

// Login.vue

<template><div class="login-page"><h2>Login</h2><div><label>Username:</label><input type="text" v-model="username"></div><div><label>Password:</label><input type="password" v-model="password"></div><button @click="login">Login</button></div></template><script>import axios from 'axios';export default {data() {return {username: '',password: '',};},methods: {async login() {const {data } = await axios.post('/api/login', {username: this.username, password: this.password });localStorage.setItem('token', data.token); // 将token存入localStorage中this.$router.push('/');},},};</script><style scoped>.login-page {width: 400px;margin: 0 auto;padding: 20px;background-color: #f8f8f8;border: 1px solid #ccc;}input {padding: 8px;border: 1px solid #ccc;border-radius: 4px;margin-bottom: 10px;}button {padding: 10px 20px;background-color: #007aff;color: white;border: none;border-radius: 4px;cursor: pointer;}</style>// Profile.vue<template><div class="profile-page"><h2>Profile</h2><div><label>Username:</label><span>{{username }}</span></div><div><label>Email:</label><span>{{email }}</span></div></div></template><script>import axios from 'axios';export default {data() {return {username: '',email: '',};},beforeRouteEnter(to, from, next) {axios.get('/api/userinfo').then(({data }) => {next(vm => {vm.username = data.username;vm.email = data.email;});}).catch(() => {next('/');});},};</script><style scoped>.profile-page {width: 400px;margin: 0 auto;padding: 20px;background-color: #f8f8f8;border: 1px solid #ccc;}label {font-weight: bold;}span {margin-left: 10px;}</style>

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。