jwt,jws和jjwt

652 阅读3分钟

这是我参与更文挑战的第14天,活动详情查看: 更文挑战

JWT

是一种标准

官网介绍 jwt.io/introductio…

全称

全称:JSON WEB TOKEN

特点

有两种实现方式:

  1. JWS ( JSON Web Signature)
  2. JWE ( JSON Web Encryption)

这里我们常用的是这种签名的方式 JWS

JWS

特点

由两个 . 分开成三部分

如下

eyJhbGciOiJIUzUxMiJ9.eyJtc2ciOiLmrKLov47lhbPms6jljZrkuLvnmoTlhazkvJflj7cg57uZ5L2g5LiA5qCq5Zub5Y-26I2JIiwic3ViIjoi57uZ5L2g5LiA5qCq5Zub5Y-26I2JIiwiaXNzIjoi57uZ5L2g5LiA5qCq5Zub5Y-26I2JIiwiZXhwIjoxNjA2NzE1NTE1fQ.ZJWNTM_0BAZ_JzR1afBsQXxGC7eXRq-3YeT6MYyrQh-xBqIg4ABteHGNkx-iawUfWRs6g9BNIOd8PUVbYrLehg

第一部分是头部 Header (使用Base64 编码,可以解码)

第二部分是载荷 Payload (使用Base64 编码,可以解码)

第三部分是签名 Signature (将前两个部分根据加密算法算出来,一般采用非对称加密的算法如 SHAHMACSHA 等等)

小知识

​ 采用Base64 编码是因为有些符号不适合在URL中传输,采用这种编码的话可以解决这种问题 有利于数据的传输转换。

​ 采用非对称加密的话,是没法根据这个字符串去解密出相应的内容出来的,所以将前两部分加签以保证信息没有被串改过。

结构介绍

如图所示 可以看到这里有两个重要的信息

  1. 头部 Header
  2. 载荷 Payload

毕竟第三部分是没法解出来的 哈哈

img

头部 Header

这里存放的是这个JWT的最基本信息 如

  1. alg :加密算法

  2. typ :类型

载荷 Payload

Payload 中装着 Claims

Claims 种类型:registered, public, private

  1. registered

    These are a set of predefined claims which are not mandatory but recommended, to provide a set of useful, interoperable claims. Some of them are: iss (issuer), exp (expiration time), sub (subject), aud(audience), and others

    额 就是说已经先注册了一些 key 给你使用,但不是强制性的

  2. public

    These can be defined at will by those using JWTs. But to avoid collisions they should be defined in the IANA JSON Web Token Registry or be defined as a URI that contains a collision resistant namespace.

    额 好像没啥用一般 哈哈哈哈

  3. private

    These are the custom claims created to share information between parties that agree on using them and are neither registered or publicclaims.

    额 这个就是你自定义的 key

    如上面博主自定义的那个 msg

    可以在这里查看jwt的各种属性含义 介绍等等 tools.ietf.org/html/rfc751…

下面简单介绍下一些已经注册的claims

  • iss: issuer

    The "iss" (issuer) claim identifies the principal that issued the JWT.
    

    jwt 的签发者

  • sub: subject

    The "sub" (subject) claim identifies the principal that is the subject of the JWT.
    

    jwt 面向的用户

  • aud: audience

    The "aud" (audience) claim identifies the recipients that the JWT is intended for.
    

    接受 jwt 的 一方

  • exp: expiration time

    The "exp" (expiration time) claim identifies the expiration time on or after which the JWT MUST NOT be accepted for processing.
    

    jwt 的过期时间

  • nbf: not before

    The "nbf" (not before) claim identifies the time before which the JWT MUST NOT be accepted for processing.
    

    在这个时间之前不处理这个jwt

  • iat: issued at

    The "iat" (issued at) claim identifies the time at which the JWT was issued.
    

    jwt 的 创建时间

  • jti:JWT ID

    The "jti" (JWT ID) claim provides a unique identifier for the JWT.
    
  • jwt的唯一标识

签名 Signature

会根据jwt头部中的算法,对 Header 和 Payload 进行签名

如:

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

最后

将这三部分结合起来,用 . 分开就是这个jwt了。😁

框架

上面说了jwt是一种标准,所以现在也有很多框架给我们使用,比如

可以在官网中看到 java有以下几个:

auth0jose4jnimbus-josejjwtfusionauthvertx

img

img

网上也有大神测试这些框架,这里博主也不多说啦 。。🐖

简单说下这个jjwt 11 的使用

JJWT

GitHub地址:github.com/jwtk/jjwt

maven 配置

注意:

  1. jdk11对应的是这个 jjwt0.11 的版本 不能正常使用 jjwt0.9的版本
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt-api</artifactId>
   <version>0.11.2</version>
</dependency>
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt-impl</artifactId>
   <version>0.11.2</version>
   <scope>runtime</scope>
</dependency>
<dependency>
   <groupId>io.jsonwebtoken</groupId>
   <artifactId>jjwt-jackson</artifactId> <!-- or jjwt-gson if Gson is preferred -->
   <version>0.11.2</version>
   <scope>runtime</scope>
</dependency>
官网例子
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import java.security.Key;

// We need a signing key, so we'll create one just for this example. Usually
// the key would be read from your application configuration instead.
Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

// 生成token
String jws = Jwts.builder().setSubject("Joe").signWith(key).compact();

// 解析token
Jwts.parserBuilder().setSigningKey(key).build().parseClaimsJws(jws).getBody();

最后

欢迎小伙伴们来一起探讨问题~

如果你觉得本篇文章还不错的话,那拜托再点点赞支持一下呀😝

让我们开始这一场意外的相遇吧!~

欢迎留言!谢谢支持!ヾ(≧▽≦*)o 冲冲冲!!

我是4ye 咱们下期很快再见!!