1.什么是JWT?

 JWT全称JSON Web Token。是为了在网络应用环境键传递声明而执行的一种基于JSON的开放标准。

2.JWT的使用场景?

  授权:一旦用户登录,每个后续请求将包括JWT,允许用户访问该令牌允许的路由,服务和资源。单点登录是一种在广泛使用JWT的功能,因为它的开销很小,并且能够在不同的域中轻松使用。

  信息交换:JSON Web令牌是在各方之间安全传输信息的好方法。因为JWT可以签名 - 例如,使用公钥/私钥对 - 您可以确定发件人是他们所说的人。此外,由于使用标头和有效负载计算签名,您还可以验证内容是否未被篡改。

3.JWT的结构组成?

  由三部分组成,用(.)进行分隔,他们是

  • 头部(header)
  • 有效载荷(payload)
  • 签名(signature)

  因此,JWT通常如下表示

  xxxxxx.yyyyy.zzzzz

  头部:

  JWT头部分是一个描述JWT元数据的JSON对象,通常如下所示

  

在上面的代码中,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。然后,这个json被编码称Base64Url,形成JWT的第一部分。

  有效载荷:

  有效载荷是JWT的主体内容部分,也是一个JSON对象,包含需要传递的数据。JWT指定七个默认字段供选择。

  iss:发行人

  exp:到期时间

  sup:主题

  aud:用户

  nbf:在此之前不可用

  iat:发行时间

  jti:JWT ID用于标识该JWT

  除以上默认字段外,我们还可以自定义私有字段,如下例:

  

  请注意,默认情况下JWT是未加密的,任何人都可以解读其内容,因此不要构建隐私信息字段,存放保密信息,以防止信息泄露。

  JSON对象也使用Base64 URL算法转换为字符串保存,形成JWT第二部分。

  签名:

  签名是对上面两部分数据签名,通过指定的算法生成哈希,以确保数据不会被篡改。

  首先,需要制定一个密钥(secret)。该密钥仅仅为保存在服务器中,并且不能向用户公开。然后,使用头部中指定的签名算法(默认情况下为HMACSHA256)根据以下公式生成签名。

  

  在计算出签名后,将JWT头部,有效载荷和签名的三个部分组合成一个字符串,每个部分用"."分隔,就构成整个JWT对象,返回给用户。

4.JWT的用法?

  JWT的原理是,服务器认证以后,生成一个JSON对象,发回给用户,如下面格式

  {
  "姓名": "张三",
   "角色": "管理员",
  "到期时间": "2018年7月1日0点0分"
  }

  以后用户与服务端通信的时候,都要返回这个JSON对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名。

  客户端收到服务器返回的JWT,可以存储到Cookie里面,也可以存储到localStorage。

  此后,客户端每次与服务器通信,都要带上这个JWT。你可以把它放在cookie里面自动发送,但是这样就不能实现跨域。所以更好的做法是放在HTTP请求的头信息Authorization字段里面

  另一种做法是,跨域的时候,JWT就放在POST请求的数据里面。

5.JWT特点?

  (1)JWT默认是不加密的,但也是可以加密的。生成原始Token以后,可以用密钥在加密一次。

  (2)JWT不加密的情况下,不能将秘密数据写入JWT。

  (3)JWT不仅可以用于认证,也可以死用于交换信息。有效使用JWT,可以降低服务器的查询数据库的次数。

  (4)JWT最大的缺点是,用于服务器不保存sessi000on状态,因此无法在使用过程中废止某个token,或者更改token的权限,也就是说,一旦JWT签发了,在到期之前就会始终有效,除非服务器部署额外的逻辑。

  (5)JWT本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减少盗用,JWT的有效期限应该设置的比较短。对于一些比较重要的权限,使用时应该再次对用户进行认证。

  (6)为了较少盗用,JWT不应该使用HTTP协议明码传输,要使用HTTPS协议传输。

7.JWT的入门案例(Java方式)

  创建一个项目,先引入依赖。

  

  创建一个Jwtutil工具类,里面有包括创建Jwt和解析Jwt

创建JWT

public String createJWT(String id, String subject, long ttlMillis) throws Exception {
//指定签名的时候使用的签名算法,也就是header那部分,jjwt已经将这部分内容封装好了
SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
//生成JWT的时间
long nowMillis = System.currentTimeMillis();
Date now = new Date(nowMillis);
//创建payload的私有声明(根据特定的业务需要添加,如果要拿这个做验证,一般是需要和jwt的接收方提前沟通好验证方式的)
Map<String,Object> claims = new HashMap<String,Object>();
  claims.put("uid", "DSSFAWDWADAS...");
  claims.put("user_name", "admin");
  claims.put("nick_name","DASDA121");
    /**
* 生成签名的时候使用的秘钥secret,这个方法本地封装了的,一般可以从本地配置文件中读取,切记这个秘钥不能外露哦。它就是你服务端的私钥,在任何场景都不应该流露出去。一旦客户端得知这个secret, 那就意味着客户端是可以自我签发jwt了。
*/
SecretKey key = generalKey();
//下面就是在为payload添加各种标准声明和私有声明了
//这里其实就是new一个JwtBuilder,设置jwt的body
JwtBuilder builder = Jwts.builder()
//如果有私有声明,一定要先设置这个自己创建的私有的声明,这个是给builder的claim赋值,一旦写在标准的声明赋值之后,就是覆盖了那些标准的声明的
.setClaims(claims)
//设置jti(JWT ID):是JWT的唯一标识,根据业务需要,这个可以设置为一个不重复的值,主要用来作为一次性token,从而回避重放攻击。
.setId(id)
//iat: jwt的签发时间
.setIssuedAt(now)
//sub(Subject):代表这个JWT的主体,即它的所有人,这个是一个json格式的字符串,可以存放什么userid,roldid之类的,作为什么用户的唯一标志。
.setSubject(subject)
//设置签名使用的签名算法和签名使用的秘钥
.signWith(signatureAlgorithm, key);
if (ttlMillis >= 0) {
long expMillis = nowMillis + ttlMillis;
Date exp = new Date(expMillis);
//设置过期时间
builder.setExpiration(exp);
}
//就开始压缩为xxxxxxxxxxxxxx.xxxxxxxxxxxxxxx.xxxxxxxxxxxxx这样的jwt
return builder.compact();
}
解析JWT
public Claims parseJWT(String jwt) throws Exception{
//签名秘钥,和生成的签名的秘钥一模一样
SecretKey key = generalKey();
//得到DefaultJwtParser
Claims claims = Jwts.parser()
//设置签名的秘钥
.setSigningKey(key)
//设置需要解析的jwt
.parseClaimsJws(jwt).getBody();
//claims相当于一个map,包含了我们想要的信息
return claims;
}

  接下来测试一下,首先创建一个jwt,得到一个xxxxxx.zzzzzz.yyyyy字符串

  

  

  我们再来解析一下这个字符串:

  

  

  这样,我们就能够根据这个字符串解析出用户信息,从而验证登录授权等功能。

JWT的入门案例的更多相关文章

  1. SpringMVC入门案例及请求流程图(关于处理器或视图解析器或处理器映射器等的初步配置)

    SpringMVC简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 Spring结构图 Spr ...

  2. SpringMvc核心流程以及入门案例的搭建

    1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...

  3. Struts2第一个入门案例

      一.如何获取Struts2,以及Struts2资源包的目录结构的了解    Struts的官方地址为http://struts.apache.org 在他的主页当中,我们可以通过左侧的Apache ...

  4. MyBatis入门案例、增删改查

    一.MyBatis入门案例: ①:引入jar包 ②:创建实体类 Dept,并进行封装 ③ 在Src下创建大配置mybatis-config.xml <?xml version="1.0 ...

  5. Hibernate入门案例及增删改查

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  6. Quartz应用实践入门案例二(基于java工程)

    在web应用程序中添加定时任务,Quartz的简单介绍可以参看博文<Quartz应用实践入门案例一(基于Web应用)> .其实一旦学会了如何应用开源框架就应该很容易将这中框架应用与自己的任 ...

  7. Quartz应用实践入门案例一(基于Web环境)

    Quartz是一个完全由java编写的开源作业调度框架,正是因为这个框架整合了许多额外的功能,所以在使用上就显得相当容易.只是需要简单的配置一下就能轻松的使用任务调度了.在Quartz中,真正执行的j ...

  8. MyBatis入门案例 增删改查

    一.MyBatis入门案例: ①:引入jar包 ②:创建实体类 Dept,并进行封装 ③ 在Src下创建大配置mybatis-config.xml <?xml version="1.0 ...

  9. Hibernate入门案例 增删改

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

随机推荐

  1. WebService它Soap头验证进入

    1.创建一个新的类.如"AuthHeaderUser",在传承"System.Web.Services.Protocols.SoapHeader"类别 2.新W ...

  2. 潜移默化学会WPF--值转换器

    原文:潜移默化学会WPF--值转换器 1. binding 后面的stringFormat的写法----连接字符串 <TextBlock Text="{Binding Path=Qty ...

  3. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探

    原文:WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探         最近因为项目需要,开始学习如何使用WPF开发桌面程序.使用WPF一段时间之后,感 ...

  4. HALCON 光圈和景深的关系

    光圈越大,越亮,景深越小 光圈越小,越暗,景深越大 景深为成像清晰的那个范围

  5. iPhone开发笔记(20)EGOImageView的使用方法及注意事项

    EGOImageView是一种实现网络图片的异步加载和缓存的第三方类库,具有相同功能的第三方类库还有SDWebImage.但是相比两个类库的安装和使用来说,EGOImageView更简单一些,下面就介 ...

  6. Bootstrap 反色导航条

    @{    Layout = null;}<!DOCTYPE html><html><head>    <meta name="viewport&q ...

  7. c# WebApi POST请求同时包含数据及其文件

    原因:创建.net WebApi的接口API.IIS作为服务端.安卓作为客户端发送json文件及其文件. Android端使用xUtils3.0实现文件上传 java代码: //要传递给服务器的jso ...

  8. Xcode自动注释插件: VVDocumenter使用和安装

    开源插件: VVDocumenter 下载地址: https://github.com/onevcat/VVDocumenter-Xcode 使用效果: 使用方法: 在方法写///,效果同上图,下面有 ...

  9. UWP 浏览本地图片及对图片的裁剪

    原文:UWP 浏览本地图片及对图片的裁剪 1.前言 准备给我的校园助手客户端添加一个修改头像的功能,但是查了好多资料都没有找到裁剪图片的简单的方法,最后才找到这个使用Launcher调用系统组件的简单 ...

  10. tensorflow 1.0 学习:模型的保存与恢复

    将训练好的模型参数保存起来,以便以后进行验证或测试,这是我们经常要做的事情.tf里面提供模型保存的是tf.train.Saver()模块. 模型保存,先要创建一个Saver对象:如 saver=tf. ...