WebApi_基于Token的身份验证——JWT

JWT是啥?

JWT就是一个字符串,通过加密处理与校验处理的字符串,形式为:php

A.B.Chtml

A由JWT头部信息header加密获得
B由JWT用到的身份验证信息json数据加密获得
C由A和B加密获得,是校验部分算法

怎样生成A?

header格式为:数据库

[csharp] view plain copy
print ?
  1. {  
  2.     "typ""JWT",  
  3.     "alg""HS256"   
  4. }  
{
    "typ": "JWT",
    "alg": "HS256" 
}

  

它就是一个json串,两个字段是必须的,不能多也不能少。alg字段指定了生成C的算法,默认值是HS256
将header用base64加密,获得A
一般,JWT库中,能够把A部分固定写死,用户最多指定一个alg的取值json

怎样计算B?

根据JWT claim set[用base64]加密获得的。claim set是一个json数据,是代表用户身份的数据,可自行指定字段很灵活,也有固定字段表示特定含义(但不必定要包含特定字段,只是推荐)。
这里偷懒,直接用php中的代码来表示claim set了,重在说明字段含义:服务器

[csharp] view plain copy
print ?
  1. $token = array(  
  2.     "iss" => "http://example.org",   #非必须。issuer 请求实体,能够是发起请求的用户的信息,也但是jwt的签发者。  
  3.     "iat" => 1356999524,                #非必须。issued at。 token建立时间,unix时间戳格式  
  4.     "exp" => "1548333419",            #非必须。expire 指定token的生命周期。unix时间戳格式  
  5.     "aud" => "http://example.com",   #非必须。接收该JWT的一方。  
  6.     "sub" => "jrocket@example.com",  #非必须。该JWT所面向的用户  
  7.     "nbf" => 1357000000,   # 非必须。not before。若是当前时间在nbf里的时间以前,则Token不被接受;通常都会留一些余地,好比几分钟。  
  8.     "jti" => '222we',     # 非必须。JWT ID。针对当前token的惟一标识  
  9.   
  10.     "GivenName" => "Jonny", # 自定义字段  
  11.     "Surname" => "Rocket",  # 自定义字段  
  12.     "Email" => "jrocket@example.com", # 自定义字段  
  13.     "Role" => ["Manager""Project Administrator"] # 自定义字段  
  14. );  
$token = array(
    "iss" => "http://example.org",   #非必须。issuer 请求实体,能够是发起请求的用户的信息,也但是jwt的签发者。
    "iat" => 1356999524,                #非必须。issued at。 token建立时间,unix时间戳格式
    "exp" => "1548333419",            #非必须。expire 指定token的生命周期。unix时间戳格式
    "aud" => "http://example.com",   #非必须。接收该JWT的一方。
    "sub" => "jrocket@example.com",  #非必须。该JWT所面向的用户
    "nbf" => 1357000000,   # 非必须。not before。若是当前时间在nbf里的时间以前,则Token不被接受;通常都会留一些余地,好比几分钟。
    "jti" => '222we',     # 非必须。JWT ID。针对当前token的惟一标识

    "GivenName" => "Jonny", # 自定义字段
    "Surname" => "Rocket",  # 自定义字段
    "Email" => "jrocket@example.com", # 自定义字段
    "Role" => ["Manager", "Project Administrator"] # 自定义字段
);

  

JWT遵循RFC7519,里面提到claim set的json数据中,自定义字段的key是一个string,value是一个json数据。所以随意编写吧,很灵活。markdown

我的初学,认为一个最基本最简单最经常使用的claim set为:cookie

$token=array( "user_id" => 123456, #用户id,代表用户 "iat" => 1356999524, #token发布时间 "exp" => 1556999524, #token过时时间 );

将claim set加密后获得B,学名payloadsession

怎样计算C?

A.B使用HS256加密(实际上是用header中指定的算法),固然加密过程当中还须要密钥(自行指定的一个字符串)。
加密获得C,学名signature,其实就是一个字符串。做用相似于CRC校验,保证加密没有问题。app

好了,如今A.B.C就是生成的token了。

怎样使用token?

能够放到HTTP请求的请求头中,一般是Authorization字段。
也有人说放到cookie。不过移动端app用cookie彷佛不方便。

token应用流程?

  1. 初次登陆:用户初次登陆,输入用户名密码
  2. 密码验证:服务器从数据库取出用户名和密码进行验证
  3. 生成JWT:服务器端验证经过,根据从数据库返回的信息,以及预设规则,生成JWT
  4. 返还JWT:服务器的HTTP RESPONSE中将JWT返还
  5. 带JWT的请求:之后客户端发起请求,HTTP REQUEST HEADER中的Authorizatio字段都要有值,为JWT
服务器端在处理到达的request以前,会将request中的Token值与保存在当前用户session中的令牌值进行比较,看是否匹配。

在处理完该request后,且在response发送给客户端以前,将会产生一个新的 Token,该Token除传给客户端之外,也会将用户session中保存的旧的Token进行替换。

这样,若是用户会退到刚才的提交页面并再次提交的话,客户端传过来的Token值和服务器端的不一致,从而有效地防止了重复提交地发生。

 

 

出处:https://blog.csdn.net/u010265681/article/details/76651765