JWT技术

JWT简介

在传统的有状态服务应用中,服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如Tomcat中的Session。

例如登录:用户登录后,我们把用户的信息保存在服务端session中,并且给用户一个cookie值,记录对应的session,然后下次请求,用户携带cookie值来(这一步有浏览器自动完成),我们就能识别到对应session,从而找到用户的信息。这种方式目前来看最方便,但在分布式应用中,由服务端保存用户状态不是一种很好的选择(服务器集群高并发),因此JWT诞生

什么是JWT

JWT(JSON WEB Token)是一个标准:
借助JSON格式数据作为WEB应用请求中的令牌,进行数据的自包含设计,实现各方安全的信息传输,在数据传输过程中还可以对数据进行加密,签名等相关处理。同时JWT也是目前最流行的跨域身份验证解决方案(其官方网址为:https://jwt.io/)。可以非常方便的在分布式系统中实现用户身份认证。

JWT加密后数据结构分析

JWT加密后数据通常由三部分构成,分别为Header(头部),Payload(负载),Signature(签名),对应其格式如下:

eyJhbGciOiJIUzI1NiJ9.eyJwZXJtaXNzaW9ucyI6InN5czpyZXM6Y3JlYXRlLHN5czpyZXM6cmV0cmlldmUiLCJleHAiOjE2MjY5MzIyNTksImlhdCI6MTYyNjkzMDQ1OSwidXNlcm5hbWUiOiJqYWNrIn0.SQrRS5nuID1Xv5GMvUgnr7xrVzB7GcRFrkNak-x16Mw

Header(头部)
Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。

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

alg属性表示: 签名的算法(algorithm),默认是 HMAC SHA256(简写HS256);
typ属性表示: 这个令牌(token:加密后的数据)的类型(type),JWT 令牌统一写为JWT(该属性自定义数据的类型)

最后,将这个 JSON 对象使用Base64URL 算法转成字符串

Payload负载

Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT规范中规定了7个官方字段,供选用:

 iss (issuer):签发人
 exp (expiration time):过期时间
 sub (subject):主题
 aud (audience):受众
 nbf (Not Before):生效时间
 iat (Issued At):签发时间
 jti (JWT ID):编号

其中重要的也就是 过期时间,剩下除了官方字段,还可以在这个部分定义私有字段,例如:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

注意:JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。这个 JSON 对象也要使用 Base64URL 算法转成字符串。

小总结
Header(头部) 和 Payload(负载)都是由Base64URL 编码进行二进制到文本字符串的编码
注意:它不是加密,只是二进制进行编码成字符串的形式

Signature(签名)
Signature 部分是对前两部分的签名,其目的是防止数据被篡改,需要以下两步:

1.需要指定一个密钥(secret)也就是盐。这个密钥只有服务器才知道,不能泄露给用户。
2.使用Header里面指定的签名算法(默认是HMAC SHA256),按照下面的公式产生签名。

HMACSHA256(
  base64UrlEncode(header) + "." + 加密盐
  base64UrlEncode(payload),
  secret)

算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户

JAVA实现JWT技术

1. 支持JWT的依赖

<dependency>
  <groupId>io.jsonwebtoken</groupId>
  <artifactId>jjwt</artifactId>
  <version>0.9.1</version>
</dependency>

2. 实现代码:基于用户信息创建token信息
创建一个包含,三部分信息:头信息/负载信息/签名信息

    //基于负载和算法创建token信息
public class JwtUtils {
	//创建一个加密的秘钥,解密时需要使用
	private static  String secret = "au12df1fs115f85811s4fd";
	
    //@param map 里面存储的是用户的信息
    //@return String  Jwt创建的字符串加密信息(用于传给用户)
    public static String generatorToken(Map<String, Object> map) {
        return  Jwts.builder()//用于获取JWT的JwtBuilder对象
       			.setSubject("token")//设置主体对象(系统的主体名称,可以不写)
                .setClaims(map)//负载信息(存储登录用户信息,敏感信息不可以存放,比如密码)
                .setExpiration(new Date(System.currentTimeMillis() + (1000*60)))//该数据失效的时间
                .setIssuedAt(new Date())//签发(签名生成发放用户)时间
                .signWith(SignatureAlgorithm.HS256, secret)//签名加密算法,以及秘钥盐
                .getExpiration()//获取令牌到期时间
                .compact();//生成令牌
    }
}

3. 实现解析JWT技术生成令牌

public class JwtTests {
	//需要解密的秘钥,必须和加密时的秘钥相同
	private static  String secret = "au12df1fs115f85811s4fd";
    public static Claims getClaimsFromToken(String token) {
        return Jwts.parser()//取一个解析器对象
                .setSigningKey(secret)//设置解析时使用的秘钥 secret为加密时的秘钥
                .parseClaimsJws(token)//通过JWT加密生成的token获取token的负载信息 
                .getBody();//拿到负载信息
    }
}

注意:当失效时间到期,在去解析则解析时会抛出JWT失效异常

JWT知识点集合

JWT 诞生的背景?

分布式架构应用平台下无状态会话时,规范令牌(通票)数据格式

JWT 是什么?

一种规范用户的令牌或者通票的数据格式,

JWT 规范定义的数据格式?

头,负载-详细内容,签名,思考一篇文章的构成

JWT 规范下JAVA相关API的应用?

jjwt依赖-Jwts
基于JWT规范下JAVA API 创建令牌,解析令牌

JWT规范中的数据格式有几部分构成?

3部分,前两部分会进行Base64编码,最会基于签名算法加密

令牌对象一般是在哪里创建?

服务端,可以创建令牌以后,响应到客户端

JWT令牌假如要存储在客户端你会存储在哪里?

Cookie,localStorage,sessionStorage

JWT令牌以怎样的方式从客户端传递到服务端?

请求参数,请求头

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值