Java中JWT的使用()

  本篇文章为你整理了Java中JWT的使用()的详细内容,包含有 Java中JWT的使用,希望能帮助你了解 Java中JWT的使用。

  JWT全称为Json Web Token

  JWT的本质就是一个字符串,它是将用户信息保存到一个Json字符串中,然后进行编码后得到一个JWT token,并且这个JWT token带有签名信息,接收后可以校验是否被篡改,所以可以用于在各方之间安全地将信息作为Json对象传输。
 

  JWT的认证流程如下:
 

  1 首先,前端通过Web表单将自己的用户名和密码发送到后端的接口,这个过程一般是一个POST请求。建议的方式是通过SSL加密的传输(HTTPS),从而避免敏感信息被嗅探
 

  2 后端核对用户名和密码成功后,将包含用户信息的数据作为JWT的Payload,将其与JWT Header分别进行Base64编码后拼接签名,形成一个JWT Token,形成的JWT Token就是一个如同lll.zzz.xxx的字符串
 

  3 后端将JWT Token字符串作为登录成功的结果返回给前端。前端可以将返回的结果保存在浏览器中,退出登录时删除保存的JWT Token即可
 

  4 前端在每次请求时将JWT Token放入HTTP请求头中的Authorization属性中(解决XSS和XSRF问题)
 

  5 后端检查前端传过来的JWT Token,验证其有效性,比如检查签名是否正确、是否过期、token的接收方是否是自己等等
 

  6 验证通过后,后端解析出JWT Token中包含的用户信息,进行其他逻辑操作(一般是根据用户信息得到权限等),返回结果
 

  JWT结构

  JWT由3部分组成:标头(header)、有效载荷(payLoad)、签名(signature)。
 

  在传输的时候,会将JWT的3部分分别进行Base64编码后用.连接形成最终传输的字符串。

  Header

  JWT头是一个描述JWT元数据的JSON对象,alg属性表示签名使用的算法,默认为HMAC SHA256(写为HS256);typ属性表示令牌的类型,JWT令牌统一写为JWT。最后,使用Base64 URL算法将上述JSON对象转换为字符串保存

  

{

 

   "alg": "HS256",

   "typ": "JWT"

  

 

  PayLoad

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

  

iss:发行人

 

  exp:到期时间

  sub:主题

  aud:用户

  nbf:在此之前不可用

  iat:发布时间

  jti:JWT ID用于标识该JWT

  

 

  除以上默认字段外,我们还可以自定义私有字段,一般会把包含用户信息的数据放到payload中,如下

  

{

 

   "id": "123",

   "name": "cheng"

  

 

  Signature

  签名哈希部分是对上面两部分数据签名,需要使用base64编码后的header和payload数据,通过指定的算法生成哈希,以确保数据不会被篡改。首先,需要指定一个密钥(secret)。该密码仅仅为保存在服务器中,并且不能向用户公开。然后,使用header中指定的签名算法(默认情况下为HMAC SHA256)根据以下公式生成签名
 

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

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

  注意JWT每部分的作用,在服务端接收到客户端发送过来的JWT token之后:
 

  header和payload可以直接利用base64解码出原文,从header中获取哈希签名的算法,从payload中获取有效数据
 

  signature由于使用了不可逆的加密算法,无法解码出原文,它的作用是校验token有没有被篡改。服务端获取header中的加密算法之后,利用该算法加上secretKey对header、payload进行加密,比对加密后的数据和客户端发送过来的是否一致。

  为了完成签名,除了用到header信息和payload信息外,还需要算法的密钥,也就是secretKey。加密的算法一般有2类:

  对称加密:secretKey指加密密钥,可以生成签名与验签

  非对称加密:secretKey指私钥,只用来生成签名,不能用来验签(验签用的是公钥)
 

  JWT的密钥或者密钥对,一般统一称为JSON Web Key,也就是JWK
 

  到目前为止,jwt的签名算法有三种:

  HMAC【哈希消息验证码(对称)】:HS256/HS384/HS512

  RSASSA【RSA签名算法(非对称)】(RS256/RS384/RS512)

  ECDSA【椭圆曲线数据签名算法(非对称)】(ES256/ES384/ES512)

  Java中使用JWT

  我这里用的是java-jwt

  

 dependency 

 

   groupId com.auth0 /groupId

   artifactId java-jwt /artifactId

   version 3.10.3 /version

   /dependency

  

 

  生成JWT的Token

  

 /**

 

   * 生成JWT token

   @Test

   void generateToken(){

   //预设一个token过期时间

   Calendar calendar = Calendar.getInstance();

   calendar.add(Calendar.HOUR,1);//过期时间为1小时

   String token = JWT.create()

   .withHeader(new HashMap ())//Header

   .withClaim("userId", 123)//PayLoad

   .withClaim("userName", "程")

   .withClaim("userId1", "456")

   .withExpiresAt(calendar.getTime())//过期时间

   .sign(Algorithm.HMAC256("12345"));//签名用的密钥secret

   System.out.println(token);

  

 

  
 

  利用base64解密工具来查看生成的JWT Token中header和payLoad的明文
 

  
 

  解析JWT字符串

  

 /**

 

   * 解析jwt字符串

   @Test

   void resolveToken(){

   String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWRJbnQiOjEyMywidXNlcklkU3RyaW5nIjoiNDU2IiwidXNlck5hbWUiOiLnqIsiLCJleHAiOjE2NzU5MTQzMDZ9.MNC-YCxt8C0t9SNbj3_XMRknkK3-PKBP5xX6_JLB8y8";

   //创建解析对象,使用的算法和secret要和创建token时保持一致

   JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("12345")).build();

   DecodedJWT decodedJWT = jwtVerifier.verify(token);

   System.out.println(decodedJWT.getPayload());//base64编码的payLoad

   Claim userIdInt = decodedJWT.getClaim("userIdInt");

   Claim userIdString = decodedJWT.getClaim("userIdString");

   Claim userName = decodedJWT.getClaim("userName");

   System.out.println("userIdInt:"+userIdInt.asInt());

   System.out.println("userIdString:"+userIdString.asString());

   System.out.println("userName:"+userName.asString());

   System.out.println("过期时间:"+new LocalDateTime(decodedJWT.getExpiresAt()));

  

 

  如果我们设置的token时间短,比如设置为1秒
 

  
 

  那么解析时为抛出如下异常
 

  非对称签名

  

private static final String RSA_PRIVATE_KEY = "...";

 

  private static final String RSA_PUBLIC_KEY = "...";

   * 生成token

   * @param payload token携带的信息

   * @return token字符串

  public static String getTokenRsa(Map String,String payload){

   // 指定token过期时间为7天

   Calendar calendar = Calendar.getInstance();

   calendar.add(Calendar.DATE, 7);

   JWTCreator.Builder builder = JWT.create();

   // 构建payload

   payload.forEach((k,v) - builder.withClaim(k,v));

   // 利用hutool创建RSA

   RSA rsa = new RSA(RSA_PRIVATE_KEY, null);

   // 获取私钥

   RSAPrivateKey privateKey = (RSAPrivateKey) rsa.getPrivateKey();

   // 签名时传入私钥

   String token = builder.withExpiresAt(calendar.getTime()).sign(Algorithm.RSA256(null, privateKey));

   return token;

   * 解析token

   * @param token token字符串

   * @return 解析后的token

  public static DecodedJWT decodeRsa(String token){

   // 利用hutool创建RSA

   RSA rsa = new RSA(null, RSA_PUBLIC_KEY);

   // 获取RSA公钥

   RSAPublicKey publicKey = (RSAPublicKey) rsa.getPublicKey();

   // 验签时传入公钥

   JWTVerifier jwtVerifier = JWT.require(Algorithm.RSA256(publicKey, null)).build();

   DecodedJWT decodedJWT = jwtVerifier.verify(token);

   return decodedJWT;

  

 

  以上就是Java中JWT的使用()的详细内容,想要了解更多 Java中JWT的使用的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: