Blog

Blog

PHODAL

鉴权:用户体验与安全的平衡艺术

鉴权,是指验证用户是否拥有访问系统的权利。它是一个系统的重要组成部分,只是我好像从来没有写过相关的文章。于是,于是,最近手不怎么疼,又刚好有几个项目有相关的问题。讨论了多次之后,我发现鉴权简直称得上是一门艺术。

不过,在开始之前,我不得不声明一下这里的场景:

  • Token 鉴权。
  • 单页面应用。

传统的 Cookie-Session 的方式,并不需要这样的方式。

基于 Token 的鉴权方案

通用的基于 Token 的鉴权方案,大致步骤如下所示:

  1. 客户端将用户名和密码等信息,发送到服务端。
  2. 服务端验证生成 Token,并以 Token 作为 Key,存储到数据库中,并返回 Token 给前端。
  3. 前端存储 Token 到前端『数据库』中。

需要注意的是,对于那些对安全要求高的系统而言,前端所需要提供的参数,不限于用户名和密码,还要有地理位置、设备相关信息等参数。

随后:

  1. 前端在每个请求中,带个授权相关的信息。
  2. 后端校验前端的 Token 是否有效,再返回给前端相应的结果。
  3. 前端处理后端返回的结果。一旦鉴权失败,则删除 Token,调用登录逻辑。

好像没的毛病,大家都是这么做的,那么到底哪来的平衡艺术?、

路由守卫基础模式

前端是以路由作为边界,来划分不同领域的。也因此,在用户进行每一个路由点击之前, 系统需要对用户是否有权限进行判断。若是用户有权限,便继续访问;若是用户没有权限,那么就返回 401,并重新登录。

基于这种鉴权模式,我们会有多种多样的路由守卫方式。在执行路由跳转时,存在这么一些基础的模式:

  1. 提交时验证。这样的系统,可能是不存在的,但是我不确定。
  2. Token 存在验证。只验证 Token 是存在的,懂技术的用户可以修改,但是后果自负(无非就是数据丢失 + 重定向)。
  3. 关键步骤二次验证。先验证是否存在 Token,随后在进行一些重要的操作之前,先进行 Token 有效性验证,再进行路由跳转。
  4. 每步二次验证。即每次在路由跳转时先进行验证,再决定是否跳转。同理于刷新页面的情形。
  5. 跳转后二次验证。先跳转到页面上,再进行二次验证。
  6. ……

于是,我们可以做一个简单的对比(从 1 到 5)。

方式 用户体验 不可破解性 额外的 API 访问 后端开发成本 前端开发成本
提交时验证 3 2 3 5
Token 存在验证 3 3 3 5
关键步骤二次验证 4 4 关键路由 4 4
每步验证 1 5 每次路由 4 3
跳转后验证 3 5 每次路由 4 3

相应的解释如下:

  • 提交时验证。提交后再告诉用户授权失败,会导致数据丢失。或者额外的前端持久化数据,而每个持久化都会带来额外的工作量。
  • Token 存在验证。当用户(开发人员)修改 Token 或者 Role 时,他/她可以访问一些不应该看到的页面。
  • 关键步骤二次验证。额外的后台 API,以及关键步骤的设计。
  • 每步验证。每次跳转时,都需要等待时间,并访问后台API——会对性能造成影响。
  • 跳转后验证。减少等待时间,但是还存在大量的后台接口访问。

对于不同的场景,都可以采用不同的方案。又或者是组合出自己需求的方案。

组合鉴权

回到我们的故事上,我们采用的是第二种方案:关键步骤二次验证

首先,我们有两个后端 API:

  • 登录鉴权 API。返回 Token 和用户信息,以及 Token 的过期时间。
  • Token 有效性 API。返回用户信息,以及 Token 的过期时间。

前端代码设计(以 Angular 为例):

  1. 鉴权守卫(AuthGuard)。进行 Token 存在验证,和 Token 过期时间验证。
  2. 角色守卫(RoleGuard)。进行角色验证
  3. HTTP 异常拦截(HTTP Interceptor)。后端返回 401 时,删除 Token 等,并引导用户重新登录。

关键名词解释:

  • Token 存在验证。在本地的浏览器里存在 Token 时,便是认证通过。
  • Token 有效期验证。将本地的 Token 生成时间,与本地时间进行对比,如果不过期,则是有效的。
  • Token 有效性验证。发送请求到后端,看 Token 是否有效,更刷新用户角色。

最后,我们的组合模式如下所示:

  1. 用户进行普通(诸如自身相关的操作),只验证 Token 是否存在 + 是否在有效期内。
  2. 在用户进行部分关键操作(诸如角色绑定菜单)之前,先进行 Token 有效性验证,随后刷新本地的用户角色。
  3. ……

反正,后端会进行一系列的权限校验,不是吗?

结论

平衡,真的是是一门艺术。


或许您还需要下面的文章:

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806
comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Engineer, Consultant, Writer, Designer

ThoughtWorks 技术专家

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《前端架构:从入门到微前端》、《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 最新技术分享

标签