什么是鉴权

鉴权也叫身份认证,指验证用户是否有系统的访问权限。就很像我们经常乘坐动车的票据(对应的标识,一定的时间范围)。

认证方式

接下来介绍几种我们工作中通常用到的认证方式。

Session-Cookie 认证

利用服务端的 Session(会话)和浏览器(客户端)的 Cookie 来实现的前后端通信认证模式。

来源

由于 HTTP 请求时是无状态的,服务端正常情况下无法得知请求发送者的身份。这个时候如果我们要记录状态,就需要在服务端创建会话,将相同客户端的请求都维护在各自的会话记录中,每当请求到达服务端时,先校验请求中的用户标识是否存在于 Session 中,如果有则表示已经认证成功,否则表示认证失败。

流程

实践

boss(我们的一个产品) 这边 Session ID 存在数据库里面,在 Memcached 里面做缓存。客户端每次调用接口的时候会通过 response headers 里面的 Set-Cookie 更新过期时间(boss 这边设置的是 6 个小时),这样做的作用是防止你在做一些复杂操作的时候,cookie 突然过期。

⚠️整个过程是比较重的,因为每次的接口调用都得更新过期时间。

优缺点

优点:

  • 简单易用,浏览器会自动带上

缺点:

  • 脱离浏览器没法用,比如原生应用

关于 Cookie 的安全问题

Cookie 属性:

提高安全性的办法

  • Expires/Max-Age 设置合理过期时间

  • HttpOnly 设置为 true

  • Secure 设置为 true(使用 https)

Token 认证

来源

负载均衡多服务器的情况,不好确认当前用户是否登录,因为多服务器不共享 Session。这个问题也可以将 Session 存在一个服务器中来解决,但是就不能完全达到负载均衡的效果。
Token 和 Session-Cookie 认证方式中的 Session ID 不同,并非只是一个标识符。Token 一般会包含用户的相关信息,通过验证 Token 不仅可以完成身份校验,还可以获取预设的信息。
客户端可以将 token 存放于 localStroage 等容器中。客户端每次访问都传递 token,服务端解密 token,服务端就不需要存储 Session 占用存储空间,就很好的解决负载均衡多服务器的问题了。

流程

实践

平常用的最多的就是 JSON Web Token(JWT),也是目前最流行的跨域身份验证解决方案。
JWT 组成:头部. 载荷. 签名
头部和载荷用 base64 编码
签名计算:

 HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload) , secret)

使用方法:

 Authorization: Bearer <token>

但是 JWT 有个大缺点是服务器不保存会话状态,所以在使用期间不可能取消令牌或更改令牌的权限。也就是说,一旦 JWT 签发,在有效期内将会一直有效。

⚠️载荷的内容任何人都可以读到,不要放入敏感信息

jwt 存储位置的争论:我觉得如果存储信息多,天然防止 csrf 的话,放到 localStorage 或者 sessionStoraged 都行。
除了 JWT 可以提升 token 的安全性,Refresh token 也可以。
业务接口用来鉴权的 token,我们称之为 access token。越是权限敏感的业务,我们越希望 access token 有效期足够短,以避免被盗用。但是过短的有效期会造成 access token 经常过期,过期后怎么办呢?
一种办法是,让用户重新登录获取新 token,显然不够友好,要知道有的 access token 过期时间可能只有几分钟。
另外一种办法是,再来一个 token,一个专门生成 access token 的 token,我们称为 refresh token。
refresh token 的过期时间一般比较长,比如 6 个小时,access token 的过期时间比较短,比如 10 分钟。我们在实际业务中,api 调用时只传递 access token 进行鉴权。如果 access token 过期,则使用 refresh token 去授权服务器更新 access token。最终 refresh token 也过期了,这时候用户就得重新登陆了。

优缺点

优点:

  • 轻量,服务端不用存储,移动端可用

缺点:

  • 一旦派发出去,失效之前都是有效的(虽然可以解决,但是就类似于 Session 机制了)

单点登录

来源

但当我们业务线越来越多,就会有更多业务系统分散到不同域名下,就需要「一次登录,全线通用」的能力,叫做「单点登录」。

流程

对浏览器来说,SSO 域下返回的数据要怎么存,才能在访问 A 的时候带上?这就需要也只能由 A 提供 A 域下存储凭证的能力。

实践

OIDC

  1. OIDC 登陆点击,重定向到登录的 OpenID 网站

  2. 输入用户名密码,如果验证成功。则会重定向到登陆回调(之前设置好的地址)

  3. 回调地址里面有个 code 参数,code 验证正确后,下发 sk,boss 系统登陆成功

  4. 前端通过添加 iframe 的方式轮询 authing 链接实现单点登出

关于 OIDC

OIDC 是一个 OAuth2 上层的简单身份层协议。它允许客户端验证用户的身份并获取基本的用户配置信息。OIDC 使用 JSON Web Token(JWT)作为信息返回,通过符合 OAuth2 的流程来获取。

关于 OAuth2

OAuth2 最终目的是为第三方应用颁发一个有时效性的令牌 token。使得第三方应用能够通过该令牌获取相关的资源。当你想要登录某个论坛,但没有账号,而这个论坛接入了如 QQ、Facebook 等登录功能,在你使用 QQ 登录的过程中就使用的 OAuth 2.0 协议。

  • Client 请求 Resource Owner 的授权。授权请求可以直接向 Resource Owner 请求,也可以通过 Authorization Server 间接的进行。

  • Client 获得授权许可。

  • Client 向 Authorization Server 请求访问令牌。

  • Authorization Server 验证授权许可,如果有效则颁发访问令牌。

  • Client 通过访问令牌从 Resource Server 请求受保护资源。

  • Resource Server 验证访问令牌,有效则响应请求。

关于 LDAP

LDAP (Light Directory Access Portocol),中文名轻量目录访问协议,是一个开放、广泛被使用的工业标准。比如我们的 Jira、Confluence、Yapi。
但是 LDAP 并不能做到单点登录 SSO,只是可以用同样的用户名和密码可以登陆不同的系统,但达不到一次登陆之后可以访问多个系统。

Others 认证方式

2FA(双因素认证)

线上的 boss 必须开启二次认证,会生成一个二维码,那个二维码就是一个 SecretKey,通过 CryptoJS.HmacSHA1(默认算法),每次会计算出一个 6 位(默认长度)随机数。计算公式为

⚠️因为默认是 30s 内有效,所以用户手机时间要比较准确

Google 验证器

密钥二维码

http://otpauth//totp/ 青云 QingCloud 云计算管理平台:deanchen@yunify.com?secret=xxx&issuer = 青云 QingCloud 云计算管理平台
xxx: 大写的字母数字 16 位

使用 base32 的解码密钥

密钥必须大写没有空格

获取 Unix 时间戳

 let epoch = Math.round(new Date().getTime() / 1000.0);if (localStorage.offset) {epoch = epoch + Number(localStorage.offset);}counter = Math.floor(epoch / period); // period 一般为30 这个失效实现的想法太棒了

计算签名

 const time = this.leftpad(this.dec2hex(counter), 16, "0");const key = this.base32tohex(secret)CryptoJS.HmacSHA1(CryptoJS.enc.Hex.parse(time),CryptoJS.enc.Hex.parse(key))

得出结果

 const len = 6;const result = otp.substr(otp.length - len, len).toString() // 默认取的最后6位

作者

Dean 青云科技高级工程师

本文由博客一文多发平台 OpenWrite 发布!

终于有人把前端鉴权讲明白了相关推荐

  1. 不服不行!终于有人把AMS和WMS讲明白了!

    现在的移动开发人才市场上,初中级开发者几乎都是人满为患,互联网公司对移动开发人员的招聘要求也越来越高,尤其是那些大厂,非常看重开发者对底层的掌握. 大家可以先来看一组大厂的面试题: AMS是如何启动的 ...

  2. 终于有人把大数据架构讲明白了

    导读:如何存储.如何利用大规模的服务器集群处理计算才是大数据技术的核心. 作者:李智慧 来源:大数据DT(ID:hzdashuju) 大数据技术其实是分布式技术在数据处理领域的创新性应用,其本质和此前 ...

  3. 终于有人把A/B测试讲明白了

    导读:对照实验有时也称为A/B测试.A/B/n 测试(强调多变体测试).实地实验.随机对照实验.分拆测试.分桶测试和平行飞行测试.本文带你了解一些相关术语及应用案例. 作者:罗恩·科哈维(Ron Ko ...

  4. 终于有人把红蓝对抗讲明白了

    导读:什么是红蓝对抗? 我们现在所处的时代,有人称为网络时代,有人称为信息时代,也有人称为数据时代,不管名字怎么叫吧,我想有一件事已经成为了共识,那就是我们的安全观念得要跟上时代发展. 都知道重要的东 ...

  5. 终于有人把如何精通C++讲明白了!

    2020年的最后1个月,C++20的标准正式公布了,它的变化有多大? 先来看一张图: 分别用C++11和C++20编写代码,来实现同一个数据操作的功能 显而易见,C++的代码变得更简洁了,甚至有人说, ...

  6. 6大准则+10道习题,终于有人把怎样选择图表讲明白了

    来源:大数据DT 本文约2300字,建议阅读7分钟 本文为大家介绍考虑图表类型时,该遵循那些指导原则. [ 导读 ] "我可以使用饼形图吗?"这里引用的提问是真实的,令人失望的是, ...

  7. 终于有人把“可解释机器学习”讲明白了

    1 为什么需要解释 机器学习模型的可解释性(Interpretability)最近说得越来越多,这也是个有趣的话题.可解释性不是个新概念,很多书在介绍机器学习模型时,都会顺带提一笔这款模型的可解释性如 ...

  8. 终于有人把ROS机器人操作系统讲明白了

    导读:机器人是多专业知识交叉的学科,通常涉及传感器.驱动程序.多机通信.机械结构.算法等,为了更高效地进行机器人的研究和开发,选择一个通用的开发框架非常必要,ROS(Robot Operating S ...

  9. 终于有人把分布式事物TCC讲明白了

    https://www.cnblogs.com/jajian/p/10014145.html

  10. 终于有人把可解释机器学习讲明白了

    导读:为了解决模型的"黑盒"问题,科学家们提出了可解释机器学习.除了预测的精准性之外,可解释性也是机器学习模型是否值得信赖的重要衡量标准. 可解释机器学习(IML)的核心思想在于选 ...

最新文章

  1. 智能家居正是扎根好时节 蓄积且待春雨
  2. python实现表格_零基础小白怎么用Python做表格?
  3. 7.Handling Missing Values
  4. Java全能手册火了!Redis/Nginx/Dubbo/Spring全家桶啥都有!
  5. shell分析日志常用指令合集
  6. poj 3411 Paid Roads (dfs)
  7. linux中fopen和open的区别,Linux下open与fopen的区别
  8. tomcat 8集合memcache所需完整jar包_使用 zabbix 监控 tomcat(包含jvm监控)
  9. 线性代数之——正交矩阵和 Gram-Schmidt 正交化
  10. 简单的图书馆系统 LibrarySystem(OC模拟)
  11. java 格雷码_在 Java 中使用递归的方式将二进制转换为等效的格雷码
  12. AcrelEMS-IDC综合能效管理系统在某大型数据中心的应用方案
  13. 天津高中计算机教案,天津高中物理教案
  14. 克隆硬盘后进不去系统_硬盘GHOST克隆后,为什么新的硬盘系统启动不了?
  15. linux 升级内核和设置默认启动内核
  16. 请假代码java web_学生请假管理系统
  17. 队列、堆、栈、堆栈的区别?
  18. base64上传为表单提交给后台的方法
  19. A - Heavy Transportation POJ - 1797
  20. 计算机专业和物联网专业课,物联网工程专业课程有哪些

热门文章

  1. 【转】微信小程序实现自动化测试
  2. EntityWrapper
  3. 写代码累了,读读这些书~
  4. 游戏程序员的2013年终总结
  5. java top virt_Java 进程占用 VIRT 虚拟内存超高的问题研究
  6. DSPE-PEG12-Mal,C72H135N2O23P长臂亲水性小分子PEG试剂
  7. CSS(层叠样式表(Cascading Style Sheets))历史
  8. 魔方cfop公式软件_如何学习魔方?这份提速心得,亲测有效
  9. Chapter04 编写基本的MapReduce程序(一) 专利数据集实战一
  10. 【Arduino连接时钟模块在LCD1602上显示时间】