• JWT快速上手 | 黑马


    JWT介绍

    JWT全称为JSON Web Token,是目前最流行的跨域身份验证解决方案。JWT是为了在网络应用环境间传递声明而制定的一种基于JSON的开放标准。

    JWT特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可被加密。

    JWT的数据结构

    jwt就是很长的json字符串,字符串之间用.分隔3个子串。每个子串表示一个功能块,jwt头(header)、有效载荷(payload)、签名(signature)

    我们看上去这些字符不是json字符串是因为进行了base64加密后再拼接的

    1、JWT头

    2、有效载荷(主体内容)

    3、签名(为了加密的过程)

    JWT的签名算法

    HS256对称加密算法,双方之间共享一个密钥,生成和验证都是一个密钥,因此必须注意密钥的安全

    RS256非对称加密算法,用公共/私钥对jwt提供方采用私钥生成,jwt使用方获取公钥验证(更安全,服务方生成,私钥保存在服务器更安全)

    jjwt介绍

    就是个提供jwt创建和验证的java库

    要导入对应的maven坐标使用

    1. <dependency>
    2. <groupId>io.jsonwebtokengroupId>
    3. <artifactId>jjwtartifactId>
    4. <version>0.9.1version>
    5. dependency>

    JWT入门案例

    1、先导入jjwt和junit的依赖

    2、编写单元测试

    1. import cn.hutool.core.io.FileUtil;
    2. import io.jsonwebtoken.*;
    3. import org.junit.Test;
    4. import java.io.DataInputStream;
    5. import java.io.InputStream;
    6. import java.security.*;
    7. import java.security.spec.PKCS8EncodedKeySpec;
    8. import java.security.spec.X509EncodedKeySpec;
    9. import java.util.HashMap;
    10. import java.util.Map;
    11. public class JwtTest {
    12. //生成jwt,不使用签名
    13. @Test
    14. public void test1(){
    15. //添加构成JWT的参数
    16. Map headMap = new HashMap();
    17. headMap.put("alg", "none");//不使用签名算法
    18. headMap.put("typ", "JWT");
    19. Map body = new HashMap();
    20. body.put("userId","1");
    21. body.put("username","xiaoming");
    22. body.put("role","admin");
    23. //用jjwt提供api生成jwt令牌
    24. String jwt = Jwts.builder()
    25. .setHeader(headMap)
    26. .setClaims(body)
    27. .setId("jwt001")
    28. .compact();
    29. System.out.println(jwt);
    30. //解析jwt
    31. Jwt result = Jwts.parser().parse(jwt);
    32. Object jwtBody = result.getBody();
    33. Header header = result.getHeader();
    34. System.out.println(result);
    35. System.out.println(jwtBody);
    36. System.out.println(header);
    37. }
    38. //生成jwt时使用签名算法生成签名部分----基于HS256签名算法
    39. @Test
    40. public void test2(){
    41. //添加构成JWT的参数
    42. Map headMap = new HashMap();
    43. headMap.put("alg", SignatureAlgorithm.HS256.getValue());//使用HS256签名算法
    44. headMap.put("typ", "JWT");
    45. Map body = new HashMap();
    46. body.put("userId","1");
    47. body.put("username","xiaoming");
    48. body.put("role","admin");
    49. //用jjwt提供api生成jwt令牌
    50. String jwt = Jwts.builder()
    51. .setHeader(headMap)
    52. .setClaims(body)
    53. .setId("jwt001")
    54. .signWith(SignatureAlgorithm.HS256,"itcast")
    55. .compact();
    56. System.out.println(jwt);
    57. //解析jwt
    58. Jwt result = Jwts.parser().setSigningKey("itcast").parse(jwt);
    59. Object jwtBody = result.getBody();
    60. Header header = result.getHeader();
    61. System.out.println(result);
    62. System.out.println(jwtBody);
    63. System.out.println(header);
    64. }
    65. //生成jwt时使用签名算法生成签名部分----基于RS256签名算法
    66. @Test
    67. public void test3() throws Exception{
    68. //添加构成JWT的参数
    69. Map headMap = new HashMap();
    70. headMap.put("alg", SignatureAlgorithm.RS256.getValue());//使用RS256签名算法
    71. headMap.put("typ", "JWT");
    72. Map body = new HashMap();
    73. body.put("userId","1");
    74. body.put("username","xiaoming");
    75. body.put("role","admin");
    76. String jwt = Jwts.builder()
    77. .setHeader(headMap)
    78. .setClaims(body)
    79. .setId("jwt001")
    80. .signWith(SignatureAlgorithm.RS256,getPriKey())
    81. .compact();
    82. System.out.println(jwt);
    83. //解析jwt
    84. Jwt result = Jwts.parser().setSigningKey(getPubKey()).parse(jwt);
    85. Object jwtBody = result.getBody();
    86. Header header = result.getHeader();
    87. System.out.println(result);
    88. System.out.println(jwtBody);
    89. System.out.println(header);
    90. }
    91. //获取私钥
    92. public PrivateKey getPriKey() throws Exception{
    93. InputStream resourceAsStream =
    94. this.getClass().getClassLoader().getResourceAsStream("pri.key");
    95. DataInputStream dis = new DataInputStream(resourceAsStream);
    96. byte[] keyBytes = new byte[resourceAsStream.available()];
    97. dis.readFully(keyBytes);
    98. PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
    99. KeyFactory kf = KeyFactory.getInstance("RSA");
    100. return kf.generatePrivate(spec);
    101. }
    102. //获取公钥
    103. public PublicKey getPubKey() throws Exception{
    104. InputStream resourceAsStream =
    105. this.getClass().getClassLoader().getResourceAsStream("pub.key");
    106. DataInputStream dis = new DataInputStream(resourceAsStream);
    107. byte[] keyBytes = new byte[resourceAsStream.available()];
    108. dis.readFully(keyBytes);
    109. X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
    110. KeyFactory kf = KeyFactory.getInstance("RSA");
    111. return kf.generatePublic(spec);
    112. }
    113. //生成自己的 秘钥/公钥 对
    114. @Test
    115. public void test4() throws Exception{
    116. //自定义 随机密码, 请修改这里
    117. String password = "itcast";
    118. KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    119. SecureRandom secureRandom = new SecureRandom(password.getBytes());
    120. keyPairGenerator.initialize(1024, secureRandom);
    121. KeyPair keyPair = keyPairGenerator.genKeyPair();
    122. byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
    123. byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();
    124. FileUtil.writeBytes(publicKeyBytes, "d:\\pub.key");
    125. FileUtil.writeBytes(privateKeyBytes, "d:\\pri.key");
    126. }
    127. }

  • 相关阅读:
    求每个店铺访问次数top3的访客信息
    Apache Seata如何解决TCC 模式的幂等、悬挂和空回滚问题
    docker安装和常用命令
    vue组件
    run isaac demo--------------------------------------------------------
    AIGC技术:发展、应用与前景
    移动端 [Android & iOS] 压缩 ECDSA PublicKey
    ubuntu 20.04.4+uWSGI+Nginx安装部署Django+Vue的web前后端全过程记录(1)
    Open AI开发者大会:AI“科技春晚”
    egg-jwt的使用
  • 原文地址:https://blog.csdn.net/weixin_54232666/article/details/127413101