vue后台管理系统流程(⾯试必选)
vue后台管理系统流程(⾯试必选)
后台页⾯的权限验证与安全性是⾮常重要的,可以说是⼀个后台项⽬⼀开始就必须考虑和搭建的基础核⼼功能 我们前端所要做的是: 不同的权限对应着不同的路由,同时侧边栏也需要根据不同的权限 , 异步⽣成.
技术栈主要有: vue,vue-router,vuex,axios,vue-cli 3.x(没有 fig.js配置⽂件,取⽽代之的是 fig.js⽂件),
fiddle.php,nodejs
(express框架配合myspl搭建过⼀个简单的后台系统框架,cookie.session配合使⽤,验证登录状态,但是我们这个项⽬使⽤的是token来验证)
⼀. 登⼊界⾯
登录: 当⽤户填写完账号和密码后向服务端验证是否正确, 服务端返回⼀个token, 拿到token之后(我会将这个token存储到cookie中,保证刷新页⾯后能记住⽤户登录), 前端会根据token在去拉取⼀个user_info的接⼝来获取⽤户的详细信息(如⽤户权限,⽤户名等等信息)
权限验证: 通过token获取⽤户对应的role(⾓⾊), 动态根据⽤户的role算出其对应有权限的路由, 通过router.addRoutes动态挂载这些路由.这些都是通过VUEX全局管理控制的(补充说在这⾥插⼊代码⽚明: 刷新页⾯后vuex的内容也会丢失)
具体实施: ⾸先做⼀个静态登⼊页⾯,两个input的框, ⼀个登录账号,⼀个登录密码,在放置⼀个登录按钮,绑定click事件,点击登录
之后向服务端提交账号和密码进⾏验证,在向服务端提交账号和密码之前我们前端还可以进⾏⼀次简单的校验,减轻服务器压⼒,优化前端代码(后台设置校验是为了防⽌有⼈绕过前端,直接去后台登⼊)
click绑定登录按钮,当点击按钮,提交账号密码,登录成功之后 , 在这⾥推荐是⽤第三⽅登录平台不重定向到⾸页,
this.showDialog = true //弹出选择第三⽅平台的dialog,利⽤this.$store.dispatch提交username信息到vuex中的异步action,并将token储存在cookie之中,这样下次打开页⾯的时候能记住⽤户的登录状态,不⽤在登录页⾯重新登录了.
注意: 为了安全性,我司在后台所有token有效期都是seeion,就是浏览器关闭了就丢失了,重新打开浏览器都需要重新登录⼀次,确保⽤户不会因为电脑遗失或者其他原因被⼈随意使⽤账号 1.1. 获取⽤户信息
⽤户登录成功之后,我们在全局钩⼦router.beforeEach中拦截路由,判断是否已获得token,在获取token之后我们就要去获取⽤户的基本信息了
(同时要注意⼀点的是: 我们之后存储⼀个⽤户token,并没有存储别的⽤户信息{⽤户名,⽤户头像等})
(假设我把⽤户权限和⽤户名存在本地,如果我在这时候有另⼀台电脑登录并修改了⾃⼰的⽤户名,那再⽤之前的电脑登录,那么他会默认去读取本地cookie中的名字,并不会去拉取新的⽤户信息)
所以现在的策略:
页⾯会从cookie中查看是否存在token
没有
2.1. (就⾛⼀遍上部分的流程重新登录)
如果有token,就会把这个token返给后端去拉取user_info,保证⽤户信息是最新的.
3.1. (如果做了单点登录功能的话, ⽤户信息存储在本地也是可以得,当你⼀台电脑登录时,另⼀台会被提下线,所以总会重新登录获取最新的内容)
⽽且从代码层⾯我建议还是把 login和get_user_info两件事分开⽐较好,在这个后端全⾯微服务的年代,后端同学也想写优雅的代码~
⼆. 权限篇
在⼯作中,前端会有⼀个路由表,他表⽰了每⼀个路由可访问的权限.
⽤户登录之后,通过token获取⽤户的role(⾓⾊信息) 动态根据⽤户的role 算出其对应应有权限的路由
再通过router.addRouetes动态挂载路由(这些都只是路由级的,后端的权限是逃不掉的)
现在,就是前端来控制页⾯级的权限,不同权限的⽤户显⽰不同的侧边栏和限制其所能进⼊的页⾯(还有少许的按钮级别的权限控制)
后端会验证每⼀个涉及请求的操作,验证其是否有该操作的权限,每⼀个后台的请求不管是get还是post都会让前端在请求header⾥⾯携带⽤户token , 后端会根据改token来验证在token是否有权限执⾏该操作,如果没有权限就会抛出⼀个对应的状态码,前端测到状态码,做出相应的操作
后台的请求: 常见的有⼀般有四种,分别对应了 增删改查 ,
PUT:
向指定资源位置上传其最新内容。
DELETE:
请求服务器删除Request-URI所标识的资源。
POST:
向指定资源提交数据,请求服务器进⾏处理(例如提交表单或者上传⽂件)。数据被包含在请求本⽂中。这个请求可能会创建新的资源或修改现有资源,或⼆者皆有。
GET:
向指定的资源发出“显⽰”请求。使⽤GET⽅法应该只⽤在读取数据,⽽不应当被⽤于产⽣“副作⽤”的操作中,例如在Web Application 中。其中⼀个原因是GET可能会被⽹络蜘蛛等随意访问。
三. 具体实现
创建vue实例的时候将vue-router挂载 , 但这个时候vue-router挂载⼀些登录或者不⽤权限的公⽤的页⾯
当⽤户登录后, 获取⽤role, 将role和路由表每个页⾯需要的权限作⽐较, ⽣成最终⽤户可访问的路由表
调⽤router.s.addRouters)添加⽤户可访问的路由 使⽤vuex管理路由表, 根据vuex中可访问的路由渲染侧边栏组件router.js中书写实现路由表:
⾸先
我们要实现如⾸页和登录页和⼀些不⽤权限的公⽤页⾯vue-router如登录页和⾸页
之后实例化vue的时候只挂载上⾯不⽤权限的路由export default new Router({routers: 上⾯的路由})
异步挂载路由: 动态需要根据权限加载路由表,在这⾥我们根据vue-router官⽅推荐的⽅法meta路线元字段(可以meta在定义路径时包含字段,写在你children⾥⾯)
标签来标⽰页⾯访问的权限有哪些 meta: {role: [‘admin’ , ‘super_editor’]}表⽰该页⾯只有admin个超级编辑才能有资格进⼊
注意事项: 这⾥有⼀个需要⾮常注意的地⽅就是404 页⾯⼀定要最后加载 , 如果放在constantRouterMap ⼀同声明了 404 , 后⾯的所有页⾯都会拦截404 main.js数据⼊⼝⽂档(关键的main.js)
在main.js中主要⽤的是
router.beforeEach(to,from,next) => {
if (ken) {
if (to.path === ‘/login’) {
next ({path: ‘/‘})
}
}
1
2
3
4
5
6
也就是登录之后,判断是否有token,
如果没有,那就在免登录⽩名单中查,
vue element admin如果有就是直接进⼊,
如果没有那么就跳转到登录页
如果有,并且⼊⼝路径to是从/login登录页中进⼊的,
那么就redirect重定向跳转到⾸页,
否则先判断当前⽤户是否已拉取完user_info信息s.roles.length === 0),
如果是,那么user_info拉取infostore.dispatch(‘GetInfo⽅法名’).then在从这个异步操作中获取所有的值,const roles = le,⽣成可访问的路由表store.dispatch(‘GenerateRoutes’, {roles}),在获取到可访问的路由表后,
我们在动态添加可访问的路由表router.s.addRouters),
在通过next({ …to , replace: true})hack⽅法 确保addRouters 已完成 , set the replace: true
如果没有拉取到info信息就返回err .catch(err => {console.log(err)})
如果当有⽤户权限的时候,说明所有可访问路由已⽣成 ,
如果没权限的页⾯会⾃动进⼊404页⾯
如果页⾯没有token时,
如果在页⾯登⼊的⽩名单中,就直接进⼊if(whiteList.indexOf(to.path) !== -1){next()},
否则全部重定向到登⼊页⾯
下⾯是store/permission.js
这⾥就是⼲⼀件是,通过⽤户权限和之前在router.js⾥⾯asyncRouterMap的每⼀个页⾯所需要的权限做匹配 , 最后返回⼀个该⽤户能够访问路由有哪些
这是⼀个vuex状态管理模式,vuex的状态管理是响应式的,当vue组件从store中读取状态的时候,若store中的状态发⽣改变 ,
那么相应的组件也会发⽣改变
但是,你不能直接改变store中的状态.改变store中的状态唯⼀的途径就是,显⽰的提交(commit ) mutation .
在vue组件中获取vuex状态 封装hasPermission函数,
判断进⼊页⾯是否需要权限,还有封装vuex中mobule模块
侧边栏
基于element-ui(vue常⽤的UI框架)的NavMenu侧边栏来实现的
遍历之前算出来的permission_routers ,
通过vuex拿到之后动态v-for渲染(这⾥因为⼀些业务需要要加很多判断,⽐如我们定义路由的时候会加很多参数)
hidden:true 是否显⽰,默认为flase
redirect: noredirect如果重定向为conredirect那么重定向不会再⾯包屑中显⽰ name: ‘router-name’
**名称由(必须设置!!)**使⽤ meta: {role title icon noCache} role: [‘admin’ , ‘editor’]将控制页⾯⾓⾊(您可以设置多个⾓⾊)
title: ‘title’⼦菜单和⾯包屑中显⽰的名称(推荐集)
icon: ‘svg-name’侧边栏中显⽰的图标 noCache: true 如果fasle,页⾯将不会被缓存(默认为false)
侧边栏⾼亮问题: element-ui官⽅給了default-active:default-active=”$route.path” 将default-active⼀直指向当前路由就可以了,就是这么简单
按钮级别权限控制
现在是通过获取到⽤户的role之后,在前端⽤v-if⼿动判断来区分不同权限对应的按钮的。
理由前⾯也说了,我们的权限判断是交给后端来做的,每个操作后端都会进⾏权限判断。⽽且我觉得其实前端真正需要按钮级别判断的地⽅不是很多,如果⼀个页⾯有很多种不同权限的按钮,我觉得更多的应该是考虑产品层⾯是否设计合理。
axios
⾸先我们通过request在每个请求头⾥⾯塞⼊token,好让后端对请求进⾏权限验证。
并创建⼀个resques,当服务端返回特殊的状态码,我们统⼀做处理,如没权限或者token失效等操作。
两步验证
⾸先考虑到安全性,简简单单⼀个账号+密码的⽅式很难保证安装性,推荐借助腾讯的或qq作为第三⽅绑定 或者是在⼀些特殊的,有参与⽀付等⼀些事关⾃⾝利益的,设置⼆级密码
账号和密码验证成功之后还需要绑定⼀个第三⽅平台验证,只需要在原有登录的逻辑上改造⼀下就好,登录成功之后,
不直接跳到⾸页⽽是让⽤户两步登录,选择登录平台,第三⽅平台登录⼀样要通过OAuth2.0授权
如还必须是你授权账号的⼀级域名。
所以你授权的域名是vue-element-admin,你就必须重定向到vue-element-admin/xxx/下⾯,所以你需要写⼀个重定向的服务,如vue-element-admin/auth/redirect?a跳到该页⾯时会再次重定向给a。
所以我们后台也需要开⼀个authredirect页⾯:代码。他的作⽤是第三⽅登录成功之后会默认跳到授权的页⾯,授权的页⾯会再次重定向回我们的后台,由于是spa,
改变路由的体验不好,我们通过window.opener.location.href的⽅式改变hash,在login.js⾥⾯再监听hash的变化。当hash变化时,获取之前第三⽅登录成功返回的code与第⼀步账号密码登录之后返回的userid⼀同发送给服务端验证是否正确,
如果正确,这时候就是真正的登录成功。
外卖后台管理系统
后台界⾯的⾸页: 是由element的
时间区间插件 , 省市区级联插件, 树形插件选择不同的⾓⾊;
这⼏个条件, 来筛选对应条件的数据 我们把后台返回的数据放到Echarts的折线图,饼状图⾥⾯,
每次登录系统每个⾓⾊看到的这个统计数据是不⼀的,这取决于我们前端利⽤token拉取的user_info接⼝中所获取的信息,参数是不⼀样的 ,这样做到了有公司管理者对公司整体的运营情况的⼀个把握
我们的有⼀些系统给⼊驻的商家时候,他们可以添加商店 , 我们审核 ,给予相应的权限,
我们前端在通过token获取roel,根据⽤户的roel动态算出其拥有权限的路由,
之后通过router.addRouters动态挂载这些路由
商户可以上传⼀些菜品 , 图⽚ , 价格等参数 ,
我们后台⼈员会检测到每个商家的经营情况 , 动态的给他们推送⼀些活动 , ⾸页置顶之类的;
这⾥我们使⽤了
element的Upload上传插件; Transfer 穿梭框插件, Form插件, Table表格插件, Pagination 分页插件
在利⽤flex布局,布局: 头部固定,左边固定,右边⾃适应
display: flex; flex
布局中分为主轴⽅向和交叉轴: 主轴⽅向: 我们在弹性容器上通过flex-direction修改主轴⽅向;
如果主轴⽅向改变那么交叉轴也会变它有⼏个属性,分为row左->右 , column上->下 , row-reverse左<-右 , column-reverse上<-下 弹性布局永远沿着主轴排列,
当主轴排列不下,我们可以通过flex-wrap进⾏换⾏ , nowrap,不换⾏ ⼀⾏显⽰ , wrap换⾏下⼀⾏显⽰ , wrap-reverse 反向换⾏ 复合属性: flex-flow = flex-drection + flex-wrap
复合属性flex = flex-grow + flex-shrink + flex-basis flex-grow: 放⼤⽐例 flex-shrink⽣效前的尺⼨ flex-basis设置的是元素在主轴上的初始尺⼨
主轴上元素的对齐⽅式: justify-content: flex-start默认左->右 , flex-end左<-右 , center居中 , space-between左右对齐中间⾃适应 , space-around平分剩余空间 交叉轴上的对齐⽅式: align-items stretch: 默认值,会在交叉轴⽅向撑满 flex-start沿前端 flex-end沿交叉轴终点对齐 center沿交叉轴中点对齐 baseline沿第⼀⾏⽂字的基线对齐…

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。