在Spring Boot中使用 jose4j 实现 JSON Web Token (JWT)
ztj100 2025-05-14 18:29 3 浏览 0 评论
JSON Web Token 或 JWT 作为服务之间安全通信的一种方式而闻名。
JWT 有两种形式:JWS 和 JWE,它们之间的区别在于 :
JWS 的有效载荷(通讯的内容)没有加密,而 JWE 是加密的。
本文将探讨 Java Spring Boot 中 JWT 的实现,学习使用jose4j在Java中创建JWS和JWE。
本文中的代码托管在以下 GitHub 存储库中: https
://github.com/brilianfird/jwt-demo
jose4j是 Java 中流行的 JWT 库之一,具有完整的功能。
<dependency>
<groupId>org.bitbucket.b_c</groupId>
<artifactId>jose4j</artifactId>
<version>0.7.12</version>
</dependency>
JSON Web Signature (JWS) 由三部分组成:
- JOSE 标头
- Payload有效载荷
- 签名
JOSE 标头:
{
alg:<font>"HS264"</font><font>
}
</font>
JOSE 标头存储有关如何处理 JWS 的元数据。alg存储有关 JWT 使用哪种签名算法的信息。
接下来,让我们检查有效载荷:
{
“sub”:“1234567890”,
“name”:“Brilian Firdaus”,
“iat”:1651422365
}
JSON 有效载荷存储我们要传输到客户端的数据。它还存储了一些 JWT 声明,以供我们验证。
在上面的示例中,我们将三个字段注册为 JWT 声明。
- sub表示用户的唯一id
- name表示用户名
- iat表示我们在一个 epoch 中创建 JWT 的时间
最后一部分是签名,它是使 JWS 安全的部分。通常,JWS 的签名将采用字节的形式。
让我们看一个 Base64 编码签名的示例:
qsg3HKPxM96PeeXl-sMrao00yOh1T0yQfZa-BsrtjHI
现在,如果我们看到上面的三个部分,您可能想知道如何将这三个部分无缝地传递给消费者。
答案是紧凑的序列化。使用紧凑序列化,我们可以轻松地与消费者共享 JWS,因为 JWS 将成为一个长字符串。
Base64.encode(JOSE 标头) + <font>"."</font><font> + Base64.encode(有效负载)+“。” + Base64.encode(签名)
</font>
结果将是:
eyJhbGciOiJIUzI1NiIsImtpZCI6IjIwMjItMDUtMDEifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkJyaWxpYW4gRmlyZGF1cyIsImlhdCI6MTY1MTQyMjM2NX0.qsg3HKPxM96PeeXl-sMraoBy00
紧凑序列化部分在 JWT 规范中也是强制性的。所以为了让 JWS 被认为是 JWT,我们必须进行紧凑的序列化。
未受保护
我们将探讨的第一种 JWS 是不受保护的 JWS。人们很少使用这种类型的 JWS(基本上只是一个常规的 JSON),但让我们首先探索一下以了解实现的基础。
让我们从创建标头开始。与之前使用算法的示例不同HS256,现在我们将不使用算法。
生成不受保护的 JWS:
@Test
<b>public</b> <b>void</b> JWS_noAlg() throws Exception {
JwtClaims jwtClaims = <b>new</b> JwtClaims();
jwtClaims.setSubject(<font>"7560755e-f45d-4ebb-a098-b8971c02ebef"</font><font>); </font><font><i>// set sub</i></font><font>
jwtClaims.setIssuedAtToNow(); </font><font><i>// set iat</i></font><font>
jwtClaims.setExpirationTimeMinutesInTheFuture(10080); </font><font><i>// set exp</i></font><font>
jwtClaims.setIssuer(</font><font>"https://codecurated.com"</font><font>); // set iss
jwtClaims.setStringClaim(</font><font>"name"</font><font>, </font><font>"Brilian Firdaus"</font><font>); </font><font><i>// set name</i></font><font>
jwtClaims.setStringClaim(</font><font>"email"</font><font>, </font><font>"brilianfird@gmail.com"</font><font>);</font><font><i>//set email </i></font><font>
jwtClaims.setClaim(</font><font>"email_verified"</font><font>, <b>true</b>); </font><font><i>//set email_verified</i></font><font>
JsonWebSignature jws = <b>new</b> JsonWebSignature();
jws.setAlgorithmConstraints(AlgorithmConstraints.NO_CONSTRAINTS);
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.NONE);
jws.setPayload(jwtClaims.toJson());
String jwt = jws.getCompactSerialization(); </font><font><i>//produce eyJ.. JWT</i></font><font>
System.out.println(</font><font>"JWT: "</font><font> + jwt);
}
</font>
让我们看看我们在代码中做了什么:
- 我们设置了一堆声明(sub, iat, exp, iss, name, email, email_verified)
- 我们将签名算法设置为NONE,算法约束设置为,NO_CONSTRAINT因为jose4j会抛出异常,因为算法缺乏安全性
- 我们将 JWS 打包在紧凑序列化中,它将生成一个包含 JWS 的字符串。结果是一个 JWT 编译的字符串。
让我们看看我们通过调用
jws.getCompactSerialization()得到什么输出:
eyJhbGciOiJub25lIn0.eyJzdWIiOiI3NTYwNzU1ZS1mNDVkLTRlYmItYTA5OC1iODk3MWMwMmViZWYiLCJpYXQiOjE2NTI1NTYyNjYsImV4cCI6MTY1MzE2MTA2NiwiaXNzIjoiaHR0cHM6Ly9jb2RlY3VyYXRlZC5jb20iLCJuYW1lIjoiQnJpbGlhbiBGaXJkYXVzIiwiZW1haWwiOiJicmlsaWFuZmlyZEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZX0.
如果我们尝试对其进行解码,我们将获得带有我们之前设置的字段的 JWS:
{
<font>"header"</font><font>: {
</font><font>"alg"</font><font>: </font><font>"none"</font><font>
},
</font><font>"payload"</font><font>: {
</font><font>"sub"</font><font>: </font><font>"7560755e-f45d-4ebb-a098-b8971c02ebef"</font><font>,
</font><font>"iat"</font><font>: 1652556266,
</font><font>"exp"</font><font>: 1653161066,
</font><font>"iss"</font><font>: </font><font>"https://codecurated.com"</font><font>,
</font><font>"name"</font><font>: </font><font>"Brilian Firdaus"</font><font>,
</font><font>"email"</font><font>: </font><font>"brilianfird@gmail.com"</font><font>,
</font><font>"email_verified"</font><font>: <b>true</b>
}
}
</font>
我们已经成功地使用 Javajose4j库创建了 JWT!
现在,让我们继续 JWT 使用的过程。
要使用 JWT,我们可以使用库JwtConsumer中的类jose4j。让我们看一个例子:
@Test
<b>public</b> <b>void</b> JWS_consume() throws Exception {
String jwt = <font>"eyJhbGciOiJub25lIn0.eyJzdWIiOiI3NTYwNzU1ZS1mNDVkLTRlYmItYTA5OC1iODk3MWMwMmViZWYiLCJpYXQiOjE2NTI1NTYyNjYsImV4cCI6MTY1MzE2MTA2NiwiaXNzIjoiaHR0cHM6Ly9jb2RlY3VyYXRlZC5jb20iLCJuYW1lIjoiQnJpbGlhbiBGaXJkYXVzIiwiZW1haWwiOiJicmlsaWFuZmlyZEBnbWFpbC5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZX0."</font><font>;
JwtConsumer jwtConsumer = <b>new</b> JwtConsumerBuilder()
</font><font><i>// required for NONE alg </i></font><font>
.setJwsAlgorithmConstraints(AlgorithmConstraints.NO_CONSTRAINTS)
</font><font><i>// disable signature requirement </i></font><font>
.setDisableRequireSignature()
</font><font><i>// require the JWT to have iat field </i></font><font>
.setRequireIssuedAt()
</font><font><i>// require the JWT to have exp field </i></font><font>
.setRequireExpirationTime()
</font><font><i>// expect the iss to be https://codecurated.com </i></font><font>
.setExpectedIssuer(</font><font>"https://codecurated.com"</font><font>)
.build();
</font><font><i>// process JWT to jwt context </i></font><font>
JwtContext jwtContext = jwtConsumer.process(jwt);
</font><font><i>// get JWS object</i></font><font>
JsonWebSignature jws = (JsonWebSignature)jwtContext.getJoseObjects().get(0);
</font><font><i>// get claims </i></font><font>
JwtClaims jwtClaims = jwtContext.getJwtClaims();
</font><font><i>// print claims as map </i></font><font>
System.out.println(jwtClaims.getClaimsMap());
}
</font>
通过使用JwtConsumer,我们可以轻松地制定有关在处理传入 JWT 时要验证的内容的规则。通过.getJoseObjects()和getJwtClaims()方法实现了一种简单的方法分别来获取 JWS 对象和声明。
现在我们知道如何在没有签名算法的情况下生成和使用 JWT,使用它来理解 JWT 会容易得多。
不同之处在于我们需要设置算法并创建一个密钥来生成/验证 JWT。
HMAC SHA-256
HMAC SHA-256(HS256)是一个具有对称密钥的MAC函数。我们需要为它的秘钥生成至少32个字节,并将其送入jose4j库中的HmacKey类以确保安全。
我们将使用Java中的SecureRandom库来确保密钥的随机性。
byte[] key = <b>new</b> byte[32];
SecureRandom secureRandom = <b>new</b> SecureRandom();
secureRandom.nextBytes(key);
HmacKey hmacKey = <b>new</b> HmacKey(key);
密钥应被视为一种凭证。因此,它应该被存储在一个安全的环境中。作为建议,你可以将其作为环境变量或存储在[Vault](
https://www.vaultproject.io/)中。
让我们看看如何创建和使用用HS256签名的JWT。
@Test
<b>public</b> <b>void</b> JWS_HS256() throws Exception {
<font><i>// generate key </i></font><font>
byte[] key = <b>new</b> byte[32];
SecureRandom secureRandom = <b>new</b> SecureRandom();
secureRandom.nextBytes(key);
HmacKey hmacKey = <b>new</b> HmacKey(key);
JwtClaims jwtClaims = <b>new</b> JwtClaims();
jwtClaims.setSubject(</font><font>"7560755e-f45d-4ebb-a098-b8971c02ebef"</font><font>); </font><font><i>// set sub </i></font><font>
jwtClaims.setIssuedAtToNow(); </font><font><i>// set iat </i></font><font>
jwtClaims.setExpirationTimeMinutesInTheFuture(10080); </font><font><i>// set exp </i></font><font>
jwtClaims.setIssuer(</font><font>"https://codecurated.com"</font><font>); // set iss
jwtClaims.setStringClaim(</font><font>"name"</font><font>, </font><font>"Brilian Firdaus"</font><font>); </font><font><i>// set name </i></font><font>
jwtClaims.setStringClaim(</font><font>"email"</font><font>, </font><font>"brilianfird@gmail.com"</font><font>);</font><font><i>//set email </i></font><font>
jwtClaims.setClaim(</font><font>"email_verified"</font><font>, <b>true</b>); </font><font><i>//set email_verified </i></font><font>
JsonWebSignature jws = <b>new</b> JsonWebSignature();
</font><font><i>// Set alg header as HMAC_SHA256 </i></font><font>
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.HMAC_SHA256);
</font><font><i>// Set key to hmacKey </i></font><font>
jws.setKey(hmacKey);
jws.setPayload(jwtClaims.toJson());
String jwt = jws.getCompactSerialization(); </font><font><i>//produce eyJ.. JWT </i></font><font>
</font><font><i>// we don't need NO_CONSTRAINT and disable require signature anymore </i></font><font>
JwtConsumer jwtConsumer = <b>new</b> JwtConsumerBuilder()
.setRequireIssuedAt()
.setRequireExpirationTime()
.setExpectedIssuer(</font><font>"https://codecurated.com"</font><font>)
</font><font><i>// set the verification key </i></font><font>
.setVerificationKey(hmacKey)
.build();
</font><font><i>// process JWT to jwt context </i></font><font>
JwtContext jwtContext = jwtConsumer.process(jwt);
</font><font><i>// get JWS object </i></font><font>
JsonWebSignature consumedJWS = (JsonWebSignature)jwtContext.getJoseObjects().get(0);
</font><font><i>// get claims </i></font><font>
JwtClaims consumedJWTClaims = jwtContext.getJwtClaims();
</font><font><i>// print claims as map </i></font><font>
System.out.println(consumedJWTClaims.getClaimsMap());
</font><font><i>// Assert header, key, and claims </i></font><font>
Assertions.assertEquals(jws.getAlgorithmHeaderValue(), consumedJWS.getAlgorithmHeaderValue());
Assertions.assertEquals(jws.getKey(), consumedJWS.getKey());
Assertions.assertEquals(jwtClaims.toJson(), consumedJWTClaims.toJson());
}
</font>
与创建一个没有签名算法的JWS相比,代码上并没有太大的区别。我们首先使用SecureRandom和HmacKey类制作密钥。由于HS256使用对称密钥,我们只需要一个密钥,我们将用它来签署和验证JWT。
我们还通过使用
jws.setAlgorithmheaderValue(
AlgorithmIdentifiers.HMAC_SHA256)将算法头值设置为HS256,并使用jws.setKey(hmacKey)设置密钥。
在JWT的使用消费者中,我们只需要通过在jwtConsumer对象上使用.setVerificationKey(hmacKey)来设置HMAC密钥,jose4j将通过解析JWS的JOSE头来自动确定在JWS中使用何种算法。
ES256
与只需要一个密钥的HS256不同,我们需要为ES256算法生成两个密钥:私钥和公钥。
我们可以使用私钥来创建和验证JWT,而我们只能使用公钥来验证JWT。由于这些特性,私钥通常被存储为凭证,而公钥可以作为JWK托管在公共场合,这样JWT的消费者就可以自己查询主机并获得密钥。
jose4j库提供了一个简单的API来生成私钥和公钥作为JWK。
EllipticCurveJsonWebKey ellipticCurveJsonWebKey = EcJwkGenerator.generateJwk(EllipticCurves.P256);
<font><i>// get private key</i></font><font>
ellipticCurveJsonWebKey.getPrivateKey();
</font><font><i>// get public key</i></font><font>
ellipticCurveJsonWebKey.getECPublicKey();
</font>
现在我们知道了如何生成密钥,用ES256算法创建JWT,这与用HS256算法创建JWT几乎一样。
...
JsonWebSignature jws = <b>new</b> JsonWebSignature();
<font><i>// Set alg header as ECDSA_USING_P256_CURVE_AND_SHA256 </i></font><font>
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
</font><font><i>// Set key to the generated private key </i></font><font>
jws.setKey(ellipticCurveJsonWebKey.getPrivateKey());
jws.setPayload(jwtClaims.toJson());
...
JwtConsumer jwtConsumer = <b>new</b> JwtConsumerBuilder()
.setRequireIssuedAt()
.setRequireExpirationTime()
.setExpectedIssuer(</font><font>"https://codecurated.com"</font><font>)
</font><font><i>// set the verification key as the public key </i></font><font>
.setVerificationKey(ellipticCurveJsonWebKey.getECPublicKey())
.build();
...
</font>
唯一不同的地方是。
- 我们将算法头设置为ECDSA_USING_P256_CURVE_AND_SHA256
- 我们在创建JWT时使用私钥
- 我们使用公钥来验证JWT
托管JWK
我们可以使用JsonWebKeySet类轻松创建JSON网络密钥集。
@GetMapping(<font>"/jwk"</font><font>)
<b>public</b> String jwk() throws JoseException {
</font><font><i>// Create public key and private key pair</i></font><font>
EllipticCurveJsonWebKey ellipticCurveJsonWebKey = EcJwkGenerator.generateJwk(EllipticCurves.P256);
</font><font><i>// Create JsonWebkeySet object</i></font><font>
JsonWebKeySet jsonWebKeySet = <b>new</b> JsonWebKeySet();
</font><font><i>// Add the public key to the JsonWebKeySet object</i></font><font>
jsonWebKeySet.addJsonWebKey(ellipticCurveJsonWebKey);
</font><font><i>// toJson() method by default won't host the private key</i></font><font>
<b>return</b> jsonWebKeySet.toJson();
}
</font>
我们还需要改变密钥解析器的一些属性。
<font><i>// Define verification key resolver</i></font><font>
HttpsJwks httpsJkws = <b>new</b> HttpsJwks(</font><font>"http://localhost:8080/jwk"</font><font>);
HttpsJwksVerificationKeyResolver verificationKeyResolver =
<b>new</b> HttpsJwksVerificationKeyResolver(httpsJkws);
JwtConsumer jwtConsumer = <b>new</b> JwtConsumerBuilder()
.setRequireIssuedAt()
.setRequireExpirationTime()
.setExpectedIssuer(</font><font>"https://codecurated.com"</font><font>)
</font><font><i>// set verification key resolver</i></font><font>
.setVerificationKeyResolver(verificationKeyResolver)
.build();
</font>
由于我们托管了JSON网络密钥集,我们需要查询主机。jose4j也通过使用
HttpsJwksVerificationKeyResolver提供了一个简单的方法来实现。
在Java中实现JWE
与JWS不同,JSON Web加密是JWT的一种类型,它是经过加密的,除了拥有私钥的人,没有人可以看到它的内容。首先,让我们看看它的一个例子。
eyJhbGciOiJFQ0RILUVTK0EyNTZLVyIsImVuYyI6IkExMjhDQkMtSFMyNTYiLCJlcGsiOnsia3R5IjoiRUMiLCJ4IjoiMEdxMEFuWUk1RVFxOUVZYjB4dmxjTGxKanV6ckxhSjhUdHYzk5MU9sayIsInkiOiJya1Q2cjlqUWhjRU1xaGtubHJ6S0hVemFKMlhWakFpWGpIWGZZU9aY0hRIiwiY3J2IjoiUC0yNTYifX0。 DUrC7Y_ejpt1n9c8wXetwU65sxkEYxG6RBsCUdokVODJBtwypL9VjQ.ydZx-UDWDN7jbGeESXvPHg.6 ksHUeeGgGj0txFNXmsSQUCnAv52tJuGR5vgrX54vnLkryPFv2ATdLwYXZz3mAjeDes4s9otz4-Fzg1IBZ4qsfCVa6_3CVdkb8BTU4OvQx23SFEgtj8zh-8ZrqZbpKIT.p-E09mQIleNCCmwX3YL-uQ
JWE的结构是:
BASE64URL(UTF8(JWE Protected Header)) || ’.’ ||
BASE64URL(JWE Encrypted Key) || ’.’ ||
BASE64URL(JWE Initialization Vector) || ’.’ ||
BASE64URL(JWE Ciphertext) || ’.’ ||
BASE64URL(JWE Authentication Tag)
而如果我们解密JWE,我们将得到以下的内容。
{
<font>"iss"</font><font>: </font><font>"https://codecurated.com"</font><font>。
</font><font>"exp"</font><font>:1654274573。
</font><font>"iat"</font><font>:1654256573。
</font><font>"sub"</font><font>: </font><font>"12345"</font><font>
}
</font>
下面看看如何创建JWE::
@Test
<b>public</b> <b>void</b> JWE_ECDHES256() throws Exception {
<font><i>// Determine signature algorithm and encryption algorithm </i></font><font>
String alg = KeyManagementAlgorithmIdentifiers.ECDH_ES_A256KW;
String encryptionAlgorithm = ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256;
</font><font><i>// Generate EC JWK </i></font><font>
EllipticCurveJsonWebKey ecJWK = EcJwkGenerator.generateJwk(EllipticCurves.P256);
</font><font><i>// Create </i></font><font>
JwtClaims jwtClaims = <b>new</b> JwtClaims();
jwtClaims.setIssuer(</font><font>"https://codecurated.com"</font><font>);
jwtClaims.setExpirationTimeMinutesInTheFuture(300);
jwtClaims.setIssuedAtToNow();
jwtClaims.setSubject(</font><font>"12345"</font><font>);
</font><font><i>// Create JWE </i></font><font>
JsonWebEncryption jwe = <b>new</b> JsonWebEncryption();
jwe.setPlaintext(jwtClaims.toJson());
</font><font><i>// Set JWE's signature algorithm and encryption algorithm </i></font><font>
jwe.setAlgorithmHeaderValue(alg);
jwe.setEncryptionMethodHeaderParameter(encryptionAlgorithm);
</font><font><i>// Unlike JWS, to create the JWE we use the public key </i></font><font>
jwe.setKey(ecJWK.getPublicKey());
String compactSerialization = jwe.getCompactSerialization();
System.out.println(compactSerialization);
</font><font><i>// Create JWT Consumer </i></font><font>
JwtConsumer jwtConsumer =
<b>new</b> JwtConsumerBuilder()
</font><font><i>// We set the private key as decryption key </i></font><font>
.setDecryptionKey(ecJWK.getPrivateKey())
</font><font><i>// JWE doesn't have signature, so we disable it </i></font><font>
.setDisableRequireSignature()
.build();
</font><font><i>// Get the JwtContext of the JWE </i></font><font>
JwtContext jwtContext = jwtConsumer.process(compactSerialization);
System.out.println(jwtContext.getJwtClaims());
}
</font>
与JWS相比,创建和消费JWE的主要区别是。
- 我们使用公钥作为加密密钥,使用私钥作为解密密钥
- 我们在JWE中没有签名,所以消费者将需要跳过签名要求
总结
在这篇文章中,我们已经学会了使用jose4j在Java中创建JWS和JWE。
相关推荐
- Java项目宝塔搭建实战MES-Springboot开源MES智能制造系统源码
-
大家好啊,我是测评君,欢迎来到web测评。...
- 一个令人头秃的问题,Logback 日志级别设置竟然无效?
-
原文链接:https://mp.weixin.qq.com/s/EFvbFwetmXXA9ZGBGswUsQ原作者:小黑十一点半...
- 实战!SpringBoot + RabbitMQ死信队列实现超时关单
-
需求背景之为什么要有超时关单原因一:...
- 火了!阿里P8架构师编写堪称神级SpringBoot手册,GitHub星标99+
-
Springboot现在已成为企业面试中必备的知识点,以及企业应用的重要模块。今天小编给大家分享一份来着阿里P8架构师编写的...
- Java本地搭建宝塔部署实战springboot仓库管理系统源码
-
大家好啊,我是测评君,欢迎来到web测评。...
- 工具尝鲜(1)-Fleet构建运行一个Springboot入门Web项目
-
Fleet是JetBrains公司推出的轻量级编辑器,对标VSCode。该款产品还在公测当中,具体下载链接如下JetBrainsFleet:由JetBrains打造的下一代IDE。想要尝试的...
- SPRINGBOOT WEB 实现文件夹上传(保留目录结构)
-
网上搜到的SpringBoot的代码不多,完整的不多,能用的也不多,基本上大部分的文章只是提供了少量的代码,讲一下思路,或者实现方案。之前一般的做法都是使用HTML5来做的,大部都是传文件的,传文件夹...
- Java项目本地部署宝塔搭建实战报修小程序springboot版系统源码
-
大家好啊,我是测评君,欢迎来到web测评。...
- 新年IT界大笑料“工行取得基于SpringBoot的web系统后端实现专利
-
先看看专利描述...
- 看完SpringBoot源码后,整个人都精神了
-
前言当读完SpringBoot源码后,被Spring的设计者们折服,Spring系列中没有几行代码是我们看不懂的,而是难在理解设计思路,阅读Spring、SpringMVC、SpringBoot需要花...
- 阿里大牛再爆神著:SpringBoot+Cloud微服务手册
-
今天给大家分享的这份“Springboot+Springcloud微服务开发实战手册”共有以下三大特点...
- WebClient是什么?SpringBoot中如何使用WebClient?
-
WebClient是什么?WebClient是SpringFramework5引入的一个非阻塞、响应式的Web客户端库。它提供了一种简单而强大的方式来进行HTTP请求,并处理来自服务器的响应。与传...
- SpringBoot系列——基于mui的H5套壳APP开发web框架
-
前言 大致原理:创建一个main主页面,只有主页面有头部、尾部,中间内容嵌入iframe内容子页面,如果在当前页面进行跳转操作,也是在iframe中进行跳转,而如果点击尾部按钮切换模块、页面,那...
- 在Spring Boot中使用 jose4j 实现 JSON Web Token (JWT)
-
JSONWebToken或JWT作为服务之间安全通信的一种方式而闻名。...
- Spring Boot使用AOP方式实现统一的Web请求日志记录?
-
AOP简介AOP(AspectOrientedProgramming),面相切面编程,是通过代码预编译与运行时动态代理的方式来实现程序的统一功能维护的方案。AOP作为Spring框架的核心内容,通...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Java项目宝塔搭建实战MES-Springboot开源MES智能制造系统源码
- 一个令人头秃的问题,Logback 日志级别设置竟然无效?
- 实战!SpringBoot + RabbitMQ死信队列实现超时关单
- 火了!阿里P8架构师编写堪称神级SpringBoot手册,GitHub星标99+
- Java本地搭建宝塔部署实战springboot仓库管理系统源码
- 工具尝鲜(1)-Fleet构建运行一个Springboot入门Web项目
- SPRINGBOOT WEB 实现文件夹上传(保留目录结构)
- Java项目本地部署宝塔搭建实战报修小程序springboot版系统源码
- 新年IT界大笑料“工行取得基于SpringBoot的web系统后端实现专利
- 看完SpringBoot源码后,整个人都精神了
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- node卸载 (33)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- exceptionininitializererror (33)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)