JSON Web Token – 在Web应用间安全地传递信息 http://blog.leapoahead.com/2015/09/06/understanding-jwt/

基于 Token 的身份验证 https://my.oschina.net/u/1771585/blog/790711

java – jwt 项目https://github.com/auth0/java-jwt

无状态Web应用集成——jwt整合shiro http://jinnianshilongnian.iteye.com/blog/2041909

 

传统身份验证的方法

HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。

解决的方法就是,当用户请求登录的时候,如果没有问题,我们在服务端生成一条记录,这个记录里可以说明一下登录的用户是谁,然后把这条记录的 ID 号发送给客户端,客户端收到以后把这个 ID 号存储在 Cookie 里,下次这个用户再向服务端发送请求的时候,可以带着这个 Cookie ,这样服务端会验证一个这个 Cookie 里的信息,看看能不能在服务端这里找到对应的记录,如果可以,说明用户已经通过了身份验证,就把用户请求的数据返回给客户端。

上面说的就是 Session,我们需要在服务端存储为登录的用户生成的 Session ,这些 Session 可能会存储在内存,磁盘,或者数据库里。我们可能需要在服务端定期的去清理过期的 Session 。

基于 Token 的身份验证方法

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  1. 客户端使用用户名跟密码请求登录
  2. 服务端收到请求,去验证用户名与密码
  3. 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
  4. 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
  5. 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
  6. 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据

JWT

实施 Token 验证的方法挺多的,还有一些标准方法,比如 JWT,读作:jot ,表示:JSON Web Tokens 。JWT 标准的 Token 有三个部分:

  • header
  • payload
  • signature

中间用点分隔开,并且都会使用 Base64 编码,所以真正的 Token 看起来像这样:

Header

header 部分主要是两部分内容,一个是 Token 的类型,另一个是使用的算法,比如下面类型就是 JWT,使用的算法是 HS256。

上面的内容要用 Base64 的形式编码一下,所以就变成这样:

Payload

Payload 里面是 Token 的具体内容,这些内容里面有一些是标准字段,你也可以添加其它需要的内容。下面是标准字段:

  • iss:Issuer,发行者
  • sub:Subject,主题
  • aud:Audience,观众
  • exp:Expiration time,过期时间
  • nbf:Not before
  • iat:Issued at,发行时间
  • jti:JWT ID

比如下面这个 Payload ,用到了 iss 发行人,还有 exp 过期时间。另外还有两个自定义的字段,一个是 name ,还有一个是 admin 。

使用 Base64 编码以后就变成了这个样子:

Signature

JWT 的最后一部分是 Signature ,这部分内容有三个部分先是用 Base64 编码的 header.payload再用加密算法加密一下加密的时候要放进去一个 Secret ,这个相当于是一个密码这个密码秘密地存储在服务端

签名的目的

最后一步签名的过程,实际上是对头部以及载荷内容进行签名。一般而言,加密算法对于不同的输入产生的输出总是不一样的。对于两个不同的输入,产生同样的输出的概率极其地小(有可能比我成世界首富的概率还小)。所以,我们就把“不一样的输入产生不一样的输出”当做必然事件来看待吧。

所以,如果有人对头部以及载荷的内容解码之后进行修改,再进行编码的话,那么新的头部和载荷的签名和之前的签名就将是不一样的。而且,如果不知道服务器加密的时候用的密钥的话,得出来的签名也一定会是不一样的

  • header
  • payload
  • secret

处理完成以后看起来像这样:

最后这个在服务端生成并且要发送给客户端的 Token 看起来像这样:

客户端收到这个 Token 以后把它存储下来,下回向服务端发送请求的时候就带着这个 Token 。服务端收到这个 Token ,然后进行验证,通过以后就会返回给客户端想要的资源

 

spring安全验证之jwt(json web token)实践 https://my.oschina.net/cccyb/blog/756436

系统开发来讲,安全验证永远是最重要的,从最原始的session、cookie验证方式,到符合restful风格、满足前后端分离需求、启用https请求,各方面都在不断变化中。本文以jwt(json web token)的实践为例,介绍一二。

首先,来看一下jwt的概念,流程图如下所示:

流程图

用户发起登录请求,服务端创建一个加密后的jwt信息,作为token返回值,在后续请求中jwt信息作为请求头,服务端正确解密后可获取到存储的用户信息,表示验证通过解密失败说明token无效或者已过期

加密后jwt信息如下所示,是由.分割的三部分组成,分别为Header、Payload、Signature。

Header包含两部分信息,alg指加密类型,可选值为HS256、RSA等等,typ=JWT为固定值,表示token的类型。

Payload是指签名信息以及内容,一般包括iss (发行者), exp (过期时间), sub(用户信息), aud (接收者),以及其他信息,详细介绍请参考官网。

Signature则为对Header、Payload的签名。

在jwt官网,可以看到有不同语言的实现版本,这里使用的是java版的jjwt。话不多说,直接看代码,加解密都很简单:

加解密的key是通过固定字符串转换而生成的;subject为用户信息的json字符串;ttlMillis是指token的有效期,时间较短,需要定时更新。

这里要介绍的token刷新方式,是在生成token的同时生成一个有效期较长的refreshToken,后续由客户端定时根据 refreshToken来获取最新的token。浏览器与服务端之间建立sse(server send event)请求,来实现刷新。关于sse在前面博文中有介绍过,此处略过不提。

本文完整源代码存放于github,地址:https://github.com/ahmu/spring-authorization-demo

参考资料:

(1)http://www.cnblogs.com/xiekeli/p/5607107.html

1.jwt官方网站:https://jwt.io/

2.jjwt项目:https://github.com/jwtk/jjwt

3.Introduction to JSON Web Tokens:https://jwt.io/introduction/

4.How to Create and verify JWTs in Java: https://stormpath.com/blog/jwt-java-create-verify