认证是任何 web 应用中不可或缺的一部分。在这个教程中,我们会讨论基于 token 的认证系统以及它和传统的登录系统的不同。这篇教程的末尾,你会看到一个使用 AngularJS 和 NodeJS 构建的完整的应用。
传统的认证系统
在开始说基于 token 的认证系统之前,我们先看一下传统的认证系统。
用户在登录域输入 用户名 和 密码 ,然后点击 登录 ;
请求发送之后,通过在后端查询数据库验证用户的合法性。如果请求有效,使用在数据库得到的信息创建一个 session,然后在响应头信息中返回这个 session 的信息,目的是把这个 session ID 存储到浏览器中;
在访问应用中受限制的后端服务器时提供这个 session 信息;
如果 session 信息有效,允许用户访问受限制的后端服务器,并且把渲染好的 HTML 内容返回。
在这之前一切都很美好。web 应用正常工作,并且它能够认证用户信息然后可以访问受限的后端服务器;然而当你在开发其他终端时发生了什么呢,比如在 Android 应用中?你还能使用当前的应用去认证移动端并且分发受限制的内容么?真相是,不可以。有两个主要的原因:
在移动应用上 session 和 cookie 行不通。你无法与移动终端共享服务器创建的 session 和 cookie。
在这个应用中,渲染好的 HTML 被返回。但在移动端,你需要包含一些类似 JSON 或者 XML 的东西包含在响应中。
在这个例子中,需要一个独立客户端服务。
基于 token 的认证
在基于 token 的认证里,不再使用 cookie 和session。token 可被用于在每次向服务器请求时认证用户。我们使用基于 token 的认证来重新设计刚才的设想。
将会用到下面的控制流程:
用户在登录表单中输入 用户名 和 密码 ,然后点击 登录 ;
请求发送之后,通过在后端查询数据库验证用户的合法性。如果请求有效,使用在数据库得到的信息创建一个 token,然后在响应头信息中返回这个的信息,目的是把这个 token 存储到浏览器的本地存储中;
在每次发送访问应用中受限制的后端服务器的请求时提供 token 信息;
如果从请求头信息中拿到的 token 有效,允许用户访问受限制的后端服务器,并且返回 JSON 或者 XML。
在这个例子中,我们没有返回的 session 或者 cookie,并且我们没有返回任何 HTML 内容。那意味着我们可以把这个架构应用于特定应用的所有客户端中。你可以看一下面的架构体系:
那么,这里的 JWT 是什么?
JWT
JWT 代表 JSON Web Token ,它是一种用于认证头部的 token 格式。这个 token 帮你实现了在两个系统之间以一种安全的方式传递信息。出于教学目的,我们暂且把 JWT 作为“不记名 token”。一个不记名 token 包含了三部分:header,payload,signature。
header 是 token 的一部分,用来存放 token 的类型和编码方式,通常是使用 base-64 编码。
payload 包含了信息。你可以存放任一种信息,比如用户信息,产品信息等。它们都是使用 base-64 编码方式进行存储。
signature 包括了 header,payload 和密钥的混合体。密钥必须安全地保存储在服务端。
你可以在下面看到 JWT 刚要和一个实例 token:
你不必关心如何实现不记名 token 生成器函数,因为它对于很多常用的语言已经有多个版本的实现。下面给出了一些:
NodeJS: auth0/node-jsonwebtoken · GitHub
PHP: firebase/php-jwt · GitHub
Java: auth0/java-jwt · GitHub
Ruby: progrium/ruby-jwt · GitHub
.NET: AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet · GitHub
Python: progrium/pyjwt · GitHub
一个实例
在讨论了关于基于 token 认证的一些基础知识后,我们接下来看一个实例。看一下下面的几点,然后我们会仔细的分析它:
多个终端,比如一个 web 应用,一个移动端等向 API 发送特定的请求。
类似 [https://api.yourexampleapp.com](https://api.yourexampleapp.com) 这样的请求发送到服务层。如果很多人使用了这个应用,需要多个服务器来响应这些请求操作。
这时,负载均衡被用于平衡请求,目的是达到最优化的后端应用服务。当你向 [https://api.yourexampleapp.com](https://api.yourexampleapp.com) 发送请求,最外层的负载均衡会处理这个请求,然后重定向到指定的服务器。
一个应用可能会被部署到多个服务器上(server-1, server-2, ..., server-n)。当有请求发送到[https://api.yourexampleapp.com](https://api.yourexampleapp.com) 时,后端的应用会拦截这个请求头部并且从认证头部中提取到 token 信息。使用这个 token 查询数据库。如果这个 token 有效并且有请求终端数据所必须的许可时,请求会继续。如果无效,会返回 403 状态码(表明一个拒绝的状态)。
如需转载,请注明文章出处和来源网址:http://www.divcss5.com/html/h63661.shtml