运维开发网

vue路由登录拦截(vue router登录权限控制)

运维开发网 https://www.qedev.com 2020-07-23 12:31 出处:网络 作者:运维开发网整理
实现原理: 哪些路由需要验证需要在路由文件router/index.js中指定: { path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/chart‘, component: Chart, name: ‘Ch

实现原理:

哪些路由需要验证需要在路由文件router/index.js中指定:

{
      path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/chart‘, component: Chart, name: ‘Chart‘, iconCls: ‘el-icon-s-flag‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }
分享图片

用户有没有登录需要给其指定状态,当用户登录了,我们用localStorage在Login.vue文件中为其状态指定为1:

that.$axios({
              method: ‘post‘, url: ‘http://localhost:9999/article/check_login_status/‘, data: param }) .then((res) => { if(res.data.ret){ localStorage.setItem("islogin", 1); // 指定登录状态 that.$router.push({path: "/table"}); }else{ that.$message(‘用户名或密码错误!‘); return false; } }) .catch((e) => { console.log(err); });
分享图片

退出时需要在Home.vue中为其指定状态为0:

localStorage.setItem("islogin", 0);
分享图片

路由拦截需要用到导航守卫,关键代码如下:

router.beforeEach((to, from, next) => {
  let islogin = localStorage.getItem("islogin"); islogin = Boolean(Number(islogin)); if(to.path == "/login"){ if(islogin){ next("/table"); }else{ next(); } }else{ // requireAuth:可以在路由元信息指定哪些页面需要登录权限 if(to.meta.requireAuth && islogin) { next(); }else{ next("/login"); } } })
分享图片

全部代码:

router/index.js:

import Vue from ‘vue‘ import Router from ‘vue-router‘ const Home = () => import(‘@/components/HelloWorld‘) const Badge = () => import(‘@/components/Badge‘) const Progress = () => import(‘@/components/Progress‘) const Table = () => import(‘@/components/Table‘) const Tag = () => import(‘@/components/Tag‘) const Chart = () => import(‘@/components/Chart‘) const NotFound = () => import(‘@/components/NotFound‘) const Login = () => import(‘@/components/Login‘) const Tabs = () => import(‘@/components/Tabs‘) const Rate = () => import(‘@/components/Rate‘) const Form = () => import(‘@/components/Form‘) Vue.use(Router) let router = new Router({ routes: [ { path: ‘/‘, component: Home, name: ‘导航一‘, iconCls: ‘el-icon-s-flag‘, leaf: false, children: [ { path: ‘/tabs‘, component: Tabs, name: ‘Tabs‘, iconCls: ‘el-icon-star-on‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } }, { path: ‘/rate‘, component: Rate, name: ‘Rate‘, iconCls: ‘el-icon-star-on‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }, { path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/badge‘, component: Badge, name: ‘Badge‘, iconCls: ‘el-icon-s-help‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }, { path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/table‘, component: Table, name: ‘Table‘, iconCls: ‘el-icon-upload‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }, { path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/tag‘, component: Tag, name: ‘Tag‘, iconCls: ‘el-icon-s-cooperation‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }, { path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/progress‘, component: Progress, name: ‘Progress‘, iconCls: ‘el-icon-s-order‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }, { path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/chart‘, component: Chart, name: ‘Chart‘, iconCls: ‘el-icon-s-flag‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }, { path: ‘/‘, component: Home, name: ‘Home‘, iconCls: ‘fa fa-address-card‘, leaf: true,//只有一个节点 children: [ { path: ‘/form‘, component: Form, name: ‘Form‘, iconCls: ‘el-icon-s-flag‘, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } } ] }, { path: ‘/login‘, name: ‘Login‘, component: Login, hidden: true, meta: { // 在路由配置中加入meta:{requireAuth: true} requireAuth: true } }, { path: ‘*‘, hidden: true, redirect: { path: ‘/404‘ } }, { path: ‘/404‘, hidden: true, name: ‘‘, component: NotFound } ] }) export default router router.beforeEach((to, from, next) => { let islogin = localStorage.getItem("islogin"); islogin = Boolean(Number(islogin)); if(to.path == "/login"){ if(islogin){ next("/table"); }else{ next(); } }else{ // requireAuth:可以在路由元信息指定哪些页面需要登录权限 if(to.meta.requireAuth && islogin) { next(); }else{ next("/login"); } } }) 
分享图片

Login.vue:

<template> <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm login-container"> <el-form-item label="用户名" prop="username"> <el-input v-model="ruleForm.username" autocomplete="off"></el-input> </el-form-item> <el-form-item label="密码" prop="password"> <el-input type="password" v-model="ruleForm.password" autocomplete="off"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm(‘ruleForm‘)">提交</el-button> <el-button @click="resetForm(‘ruleForm‘)">重置</el-button> </el-form-item> </el-form> </template> <script> export default { data() { return { ruleForm: { username: ‘‘, password: ‘‘ }, rules: { username: [ { required: true, message: ‘请输入用户名‘, trigger: ‘blur‘ }, { min: 3, max: 5, message: ‘长度在 3 到 5 个字符‘, trigger: ‘blur‘ } ], password: [ { required: true, message: ‘请输入密码‘, trigger: ‘blur‘ }, { min: 3, max: 8, message: ‘长度在 3 到 8 个字符‘, trigger: ‘blur‘ } ] } }; }, methods: { submitForm(formName) { let that = this; let param = new URLSearchParams(); param.append(‘username‘, that.ruleForm.username); param.append(‘password‘, that.ruleForm.password); this.$refs[formName].validate((valid) => { if (valid) { that.$axios({ method: ‘post‘, url: ‘http://localhost:9999/article/check_login_status/‘, data: param }) .then((res) => { if(res.data.ret){ localStorage.setItem("islogin", 1); console.log(localStorage.getItem("islogin")); that.$router.push({path: "/table"}); }else{ that.$message(‘用户名或密码错误!‘); return false; } }) .catch((e) => { console.log(err); }); } else { console.log(‘error submit!!‘); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); } } } </script> <style scoped> .login-container { /*box-shadow: 0 0px 8px 0 rgba(0, 0, 0, 0.06), 0 1px 0px 0 rgba(0, 0, 0, 0.02);*/ -webkit-border-radius: 5px; border-radius: 5px; -moz-border-radius: 5px; background-clip: padding-box; margin: 180px auto; width: 350px; padding: 35px 35px 15px 35px; background: #fff; border: 1px solid #eaeaea; box-shadow: 0 0 25px #cac6c6; .title { margin: 0px auto 40px auto; text-align: center; color: #505458; } .remember { margin: 0px 0px 35px 0px; } } </style>
分享图片

Home.vue:

<template> <div id="app"> <el-container> <el-header>Header <el-button @click="loginOut">退出</el-button></el-header> <el-container> <el-aside width="200px"> <el-row class="tac"> <el-col :span="24"> <el-menu :default-active="$route.path" router unique-opened class="el-menu-vertical-demo" @open="handleOpen" @close="handleClose"> <template v-for="(item, index) in $router.options.routes" v-if="!item.hidden"> <!--二级菜单--> <template v-if="!item.leaf" > <el-submenu :index="index+‘‘"> <template slot="title"> <i :class="item.iconCls"></i> <span>{{item.name}}</span> </template> <el-menu-item-group> <el-menu-item :index="child.path" :key="index" v-for="(child, index) in item.children"> {{child.name}} </el-menu-item> </el-menu-item-group> </el-submenu> </template> <!--一级菜单--> <template v-else> <el-menu-item :index="child.path" :key="child.path" v-for="(child, index) in item.children"> <i :class="child.iconCls"></i> <span slot="title">{{child.name}}</span> </el-menu-item> </template> <!-- <subMenu v-else :data="item" :key="key"></subMenu> --> </template> </el-menu> </el-col> </el-row> </el-aside> <el-main> <el-row> <el-col :span="24"> <div class="grid-content" style="padding: 20px;"> <router-view/> </div> </el-col> </el-row> </el-main> </el-container> </el-container> </div> </template> <script> import {mapState, mapGetters, mapActions} from ‘vuex‘ export default { name: ‘App‘, methods: { handleOpen(key, keyPath) { //console.log(key, keyPath); }, handleClose(key, keyPath) { //console.log(key, keyPath); }, ...mapActions(‘People‘, [‘asyncSetName‘]), asyncSetAge(){ this.$store.dispatch("People/asyncSetAge", 1); }, asyncSetAddress(){ this.$store.dispatch("People/asyncSetAddress", "中国湖南长沙"); }, asyncSetJob(){ this.$store.dispatch("People/asyncSetJob", "P9"); }, loginOut(){ localStorage.setItem("islogin", 0); this.$router.push("/login"); } }, computed: { ...mapState(‘People‘, [‘name‘, ‘age‘, ‘address‘, ‘job‘]), ...mapState(‘Product‘, { productName: ‘name‘, count: ‘count‘, price(state){return state.price}, mount: state => state.mount }), } } </script> <style> body{ margin: 0; } #app { font-family: ‘Avenir‘, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; } .el-row { margin-bottom: 20px; &:last-child { margin-bottom: 0; } } .el-col { border-radius: 4px; } .bg-purple-dark { background: #99a9bf; } .bg-purple { background: #d3dce6; } .bg-purple-light { background: #e5e9f2; } .grid-content { border-radius: 4px; min-height: 36px; } .row-bg { padding: 10px 0; background-color: #f9fafc; } .el-header, .el-footer { background-color: #235d8b; color: #ffffff; text-align: left; line-height: 60px; position: absolute; top: 0; left: 0; height: 60px; width: 100%; z-index: 100; } .el-aside { background-color: #4175a4; color: #ffffff; text-align: left; height: 100%; z-index: 10; position: absolute; left: 0; top: 0; padding-top: 80px; } .el-main { background-color: #FFFFFF; color: #333; text-align: left; height: 100%; position: absolute; left: 0; top: 0; padding-top: 80px; padding-left: 210px; width: 100%; } body > .el-container { margin-bottom: 40px; } .el-container:nth-child(5) .el-aside, .el-container:nth-child(6) .el-aside { line-height: 260px; } .el-container:nth-child(7) .el-aside { line-height: 320px; } .el-menu-vertical-demo{ background:#4175a4; } </style> 
分享图片

django代码:views.py

@csrf_exempt def check_login_status(request): return_dict = {"ret": False} if request.method == "POST": username = request.POST.get(‘username‘) password = request.POST.get(‘password‘) if username == ‘admin‘ and password == ‘123456‘: return_dict[‘ret‘] = True return HttpResponse(json.dumps(return_dict), content_type="application/json")
分享图片
0

精彩评论

暂无评论...
验证码 换一张
取 消