基于JWT实现的API网关

git仓库地址git

1 身份验证

1.1 传统的身份验证

HTTP是一种无状态的协议,服务器接收一个来自客户端的request,处理完之后返回一个response。可是这个过程当中,服务器几乎没有什么信息能够用来判断是哪一个客户端(用户)发来的request。此时若是用户使用帐户和密码登陆,下回再发送请求时,还得再登陆一遍。算法

1.1.1 方案一(cookie)

当用户登陆成功后,咱们直接把用户信息保存到cookie中,此后客户端的每一次请求都会带上这个cookie。tomcat

缺点:用户信息都保存在cookie中,容易被cokkie劫持安全

1.1.2 方案二(session)

当用户登陆成功后,咱们在服务端建立一个session对象,session会生成全局惟一标识符(JSESSIONID),把登陆后的用户信息都保存在这个session对象中。而后服务端只要把JSESSIONID设置到cookie,此后客户端的每一次请求都会带上这个JSESSIONID。服务器

缺点:系统一旦断电或重启,全部的会话数据都会丢失。特别是后台部署新版本,每次重启tomcat,用户都须要从新登陆。cookie

1.2 基于TOKEN的身份验证

使用基于Token的身份验证流程以下:session

基于Token的认证,除了能避免传统身份验证的问题外,还有许多额外的优势:分布式

  1. 无状态:因为Token已经包含了用户的全部信息,因此无需再存储Session
  2. 解耦:无需被绑定在一个特定的验证方案。做为独立的会话系统,利于实现分布式
  3. 基于标准:JWT做为Token的标准已经被普遍地接受。主流语言都有相应支持JWT标准的工具包

1.3 JWT

1.3.1 JWT的主要使用场景

  • 身份验证

一旦用户完成了登陆,在接下来的每一个请求中都会包含JWT,能够用来验证用户身份以及对路由,服务和资源的访问权限进行验证。目前的单点登陆(SSO)比较普遍地使用了该技术。工具

  • 信息交换

在通讯的双方之间使用JWT对数据进行编码是一种很是安全的方式,因为它的信息是通过签名的,因此能够确保发送者发送的信息是没有通过伪造的。编码

1.3.2 JWT的结构

JWT包含了使用 . 分隔的三部分:头部(Header)、载荷(Payload)与签名(Signature)

其结构看起来是这样的:

eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0OTI3NTgxNDksInN1YiI6IkpXVFRva2VuIiwiYXVkIjoia2xkIiwiaXNzIjo.8izVDNnjr8qA-3twii6O0U3FCt0-tdtNHG6eT3LMiBY

Header

在header中一般包含了两部分:token类型和采用的加密算法:

{
      "typ" : "JWT",
      "alg" : "HS256"
}

Payload

Payload部分包含了一些跟这个token有关的重要信息。经常使用的有:

  • iss:The issuer of the token,token发行人 
  • exp:Expiration Time,过时时间戳
  • sub:The subject of the token,面向的用户
  • aud:to whom the token is intended to be sent,接收方
  • iat:签发时间

Payload示例:

{exp=1492771410, sub=org-gateway, aud=kld, iss=dahai, jti=v1, iat=1492767810}

Signature

签名主要用于验证token是否有效,是否被篡改。签名时可使用加密算法进行签名,例如但愿使用HMACSHA256算法进行签名:

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

1.3.3 JWT的安全设置

JWT字符串设置到Cookie时必须使用HttpOnly属性来防止Cookie被JavaScript读取,从而避免跨站脚本攻击(XSS攻击)。

 

 参考

  • jwt.io
  • 基于Token的认证和基于声明的标识
  • JSON Web Token (JWT) 简介
  • 八幅漫画理解使用JSON Web Token设计单点登陆系统
  • jpadilla/pyjwt
相关文章
相关标签/搜索