JWT
对https://scotch.io/tutorials/the-ins-and-outs-of-token-based-authentication进行了简单翻译
介绍
基于Token 的验证如今在Web上随处可见,随着大多数互联网公司都使用API,Token成为处理多个用户验证的最好方式。
在为应用程序选择基于令牌的身份验证时,有一些非常重要的因素。
- 使用Token的主要原因如下:
- 无状态且可伸缩的服务器
- 准备采用移动应用程序
- 传递验证给其他应用程序
- 需求额外的安全措施
谁使用基于Token的验证?
您遇到的大多数API或web应用程序,例如Facebook、Twitter、 Google+、GitHub等,都很可能使用了Token.
让我们来看看它是如何工作的。
为什么Token会出现?
在了解基于Token的身份验证的工作原理及其好处之前,我们必须先了解过去进行身份验证的方式。
基于服务器的身份验证(传统的措施)
由于HTTP协议是无状态的,这意味着如果我们使用用户名和密码对用户进行身份验证,那么在下一个请求中,应用程序将不知道我们是谁,必须再次认证。
让应用程序记住我们是谁的传统方法是将登录信息存储在服务器上。这可以在Session上以一些不同的方式实现,通常是在内存中或存储在磁盘上。
这是一个基于服务器的认证工作流程的图表:
随着web、应用程序和移动应用程序的兴起,这种身份验证方法出现了问题,尤其是在可伸缩性方面。
基于服务器身份验证所出现的问题
这种认证方法出现了的主要问题如下:
Sessions: 每次对用户进行身份验证时,服务器都需要在服务器上的某处创建一条记录。这通常在内存中完成,当有很多用户进行身份验证时,服务器上的开销就会增加。
Scalability:由于会话存储在内存中,这就带来了可伸缩性方面的问题。当云服务供应商开始增添服务器来处理应用程序负载时,在Session内存中存储重要信息将限制我们的扩展能力。
CORS: 因为我们想要扩展我们的应用程序,使我们的数据可以跨多个移动设备使用,所以我们不得不担心跨域资源共享(CORS)。当使用AJAX调用从另一个域(移动端到API服务器端)获取资源时,我们可能会遇到禁止请求的问题。
CSRF: 我们还将对跨站点请求伪造(CSRF)提供保护。用户很容易受到CSRF攻击,因为他们已经在银行站点进行身份验证,在访问其他站点时可以被利用。
在这些问题中,可伸缩性是主要问题,尝试其他的方法对解决这一问题是有意义的。
基于Token的验证是如何工作的
基于Token身份验证是无状态的。我们不会在服务器或Session中存储关于用户的任何信息。
这个概念只解决了必须在服务器上存储信息的相关问题。
没有Session信息意味着您的应用程序可以根据需要扩展和添加更多的机器,而不必担心用户登录在哪里。
虽然具体实现可能有所不同,但其要点如下:
- 用户使用用户名/密码请求访问
- 应用程序验证凭证
- 应用程序向客户端提供签名Token
- 客户端存储该令牌并将其与每个请求一起发送
- 服务器验证令牌并使用数据进行响应
每个请求都需要Token。这个Token应该在HTTP头中发送,以便我们保持无状态HTTP请求的概念。我们还需要将服务器设置为可接收接受来自所有域的Access-Control-Allow-Origin:*
请求。在ACAO标头中指定*
的有趣之处在于,它不允许请求提供诸如HTTP身份验证、客户端SSL证书或cookie之类的凭证。
这里有一个图表来解释这个过程:
一旦我们用我们的Token进行了身份验证,并且有了Token,我们就可以用这个令牌做很多事情。
我们甚至可以创建一个基于权限的Token,并将其传递给第三方应用程序(比如我们想要使用的一个新的移动应用程序),这样他们就可以访问我们的数据——但只能访问我们允许使用指定Token的信息。
Token的优点
Stateless and Scalable
存储在客户端上的Token。完全无状态,可以进行扩展。由于没有任何状态或会话信息,负载均衡器可以将用户传递到任何服务器。
如果我们要将会话信息保存在已登录的用户上,这将要求我们继续将该用户发送到他们在登录时的相同服务器(称为会话关联)。
这带来了一些问题,因为一些用户将被迫使用相同的服务器,这可能导致大量的流量。
不过别担心!这些问题随Token一起消失了,因为Token本身持有该用户的数据。
安全
每个请求都会发送令牌,而不是cookie。由于没有发送cookie,这有助于防止CSRF攻击。即使您的特定实现将令牌存储在客户端cookie中,cookie也只是一种存储机制,而不是身份验证机制。没有基于会话的信息要操作,因为我们没有会话!
令牌在设定的时间之后也会过期,因此需要用户再次登录。这有助于我们保持安全。还有令牌撤销的概念,它允许我们基于相同的授权授予使特定令牌失效,甚至使一组令牌失效。
Extensibility (Friend of A Friend and Permissions)
令牌将允许我们构建与另一个共享权限的应用程序。例如,我们将随机的社交账户与我们的主要账户(如Facebook或Twitter)连接起来。
当我们通过一个服务(比方说Buffer)登录到Twitter时,我们允许Buffer向我们的Twitter流发布消息。
通过使用令牌,这就是我们为第三方应用程序提供选择性权限的方式。我们甚至可以构建我们自己的API,如果我们的用户想让另一个应用程序访问他们的数据,我们还可以分发特殊的权限令牌。
多个平台和领域
我们之前讨论过CORS。当我们的应用程序和服务扩展时,我们需要提供对各种设备和应用程序的访问(因为我们的应用程序肯定会变得很流行!)
让我们的API只服务于数据,我们还可以选择服务于CDN的资产。这消除了CORS在为我们的应用程序设置一个快速头文件配置后所带来的问题。
Access-Control-Allow-Origin: *
只要用户有一个有效的令牌,我们的数据和资源就可以用于任何域的请求。
基于标准的
在创建令牌时,您有一些选项。在后续的文章中,当我们保护一个API时,我们将更深入地讨论这个主题,但是使用的标准是JSON Web令牌。
这个方便的调试器和库图显示了对JSON Web令牌的支持。您可以看到,它在各种语言中都有大量的支持。这意味着如果您将来选择这样做,那么您实际上可以关闭您的身份验证机制!
结论
这只是对基于令牌的身份验证的方式和原因的介绍。在安全领域中,每个主题都有很多(太多了?),并且每个用例都不同。我们甚至深入探讨了一些关于可伸缩性的话题,这些话题也值得讨论。
这是一个高水平的快速概述,所以请随时指出任何遗漏的地方或您在这个问题上的任何问题。