英文:
How to Get JSON String for header/payload from JWT token using java-jwt
问题
以下是翻译好的内容:
在java-jwt中是否有一个方法可以将令牌作为单个JSON字符串返回(或者至少将头部和载荷作为两个JSON字符串返回)?JJWT是否支持这一点?
查看https://github.com/auth0/java-jwt上的教程,我没有看到这个方法(虽然有用于消息各个部分的单独getter,但我没有看到返回完整消息作为JSON字符串的内容)。
getHeader()和getHeader()方法返回编码后的字符串。我正在尝试获取头部和载荷作为JSON(类似于https://jwt.io/上显示的内容)。我该如何做?
这是目前的代码:
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
public class CreateTokenExampleIntegrationTest {
private static final Logger logger = LoggerFactory.getLogger(CreateTokenExampleIntegrationTest.class);
@Test
public void shouldCreateToken() {
logger.info("Starting test...");
// 创建令牌
String key = "foobarkey";
Algorithm alg = Algorithm.HMAC256(key);
String issuer = "me";
JWTCreator.Builder jwt = JWT.create();
jwt.withIssuer(issuer);
jwt.withClaim("createdBy", "CreateTokenExampleIntegrationTest");
jwt.withClaim("purpose", "test");
jwt.withClaim("msg", "Hello World.");
String token = jwt.sign(alg);
logger.info("Created token: \n" + token);
// 读取令牌
JWTVerifier verifier = JWT.require(alg)
.withIssuer(issuer)
.build();
DecodedJWT decoded = verifier.verify(token);
logger.info("Header: \n" + decoded.getHeader());
logger.info("Payload: \n" + decoded.getPayload());
logger.info("Done.");
}
}
这是输出:
2020-05-19 08:23:31,387 08:23:31.387 [main] INFO (CreateTokenExampleIntegrationTest.java:19) - Starting test...
2020-05-19 08:23:32,226 08:23:32.226 [main] INFO (CreateTokenExampleIntegrationTest.java:30) - Created token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJbnRlZ3JhdGlvblRlc3QiLCJwdXJwb3NlIjoidGVzdCIsImlzcyI6Im1lIn0.VmYsToj1PKBzJKQuXEyiKuJA-GkNVit0Ylh44dVF2UI
2020-05-19 08:23:32,273 08:23:32.273 [main] INFO (CreateTokenExampleIntegrationTest.java:36) - Header:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2020-05-19 08:23:32,273 08:23:32.273 [main] INFO (CreateTokenExampleIntegrationTest.java:37) - Payload:
eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJbnRlZ3JhdGlvblRlc3QiLCJwdXJwb3NlIjoidGVzdCIsImlzcyI6Im1lIn0
2020-05-19 08:23:32,273 08:23:32.273 [main] INFO (CreateTokenExampleIntegrationTest.java:38) - Done.
编辑:这是基于接受答案的完整解决方案:
代码:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
public class CreateTokenExampleIntegrationTest {
private static final Logger logger = LoggerFactory.getLogger(CreateTokenExampleIntegrationTest.class);
@Test
public void shouldCreateToken() {
logger.info("Starting test...");
// 创建令牌
String key = "foobarkey";
Algorithm alg = Algorithm.HMAC256(key);
String issuer = "me";
JWTCreator.Builder jwt = JWT.create();
jwt.withIssuer(issuer);
jwt.withClaim("createdBy", "CreateTokenExampleIntegrationTest");
jwt.withClaim("purpose", "test");
jwt.withClaim("msg", "Hello World.");
String token = jwt.sign(alg);
logger.info("Created token: \n" + token);
// 读取令牌
JWTVerifier verifier = JWT.require(alg)
.withIssuer(issuer)
.build();
DecodedJWT decoded = verifier.verify(token);
// 头部
String encHeader = decoded.getHeader();
String header = decode(encHeader);
logger.info("Header: \n" + encHeader + "\n" + header);
// 载荷
String encPayload = decoded.getPayload();
String payload = decode(encPayload);
logger.info("Payload: \n" + encPayload + "\n" + payload);
// 完成
logger.info("Done.");
}
public String decode(final String base64) {
return StringUtils.newStringUtf8(Base64.decodeBase64(base64));
}
}
输出:
2020-05-19 10:13:29,146 10:13:29.146 [main] INFO (CreateTokenExampleIntegrationTest.java:21) - Starting test...
2020-05-19 10:13:30,031 10:13:30.031 [main] INFO (CreateTokenExampleIntegrationTest.java:32) - Created token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJ
<details>
<summary>英文:</summary>
Is there a method in java-jwt that will return the token as a single JSON string (or at least the header and payload as two JSON strings)? Does JJWT support this?
Looking at the tutorial at https://github.com/auth0/java-jwt I'm not seeing this method (there are individual getters for individual pieces of the message but I'm not seeing anything that returns the complete message as a JSON string).
The getHeader() and getHeader() methods return the encoded strings. I'm trying to get the headers and payload as JSON (similar to what is shown at https://jwt.io/). How do I do this?
Here's the code so far:
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
public class CreateTokenExampleIntegrationTest {
private static final Logger logger = LoggerFactory.getLogger(CreateTokenExampleIntegrationTest.class);
@Test
public void shouldCreateToken() {
logger.info("Starting test...");
// create the token
String key = "foobarkey";
Algorithm alg = Algorithm.HMAC256(key);
String issuer = "me";
JWTCreator.Builder jwt = JWT.create();
jwt.withIssuer(issuer);
jwt.withClaim("createdBy", "CreateTokenExampleIntegrationTest");
jwt.withClaim("purpose", "test");
jwt.withClaim("msg", "Hello World.");
String token = jwt.sign(alg);
logger.info("Created token: \n" + token);
// read the token
JWTVerifier verifier = JWT.require(alg)
.withIssuer(issuer)
.build();
DecodedJWT decoded = verifier.verify(token);
logger.info("Header: \n" + decoded.getHeader());
logger.info("Payload: \n" + decoded.getPayload());
logger.info("Done.");
}
}
And here's the output:
2020-05-19 08:23:31,387 08:23:31.387 [main] INFO (CreateTokenExampleIntegrationTest.java:19) - Starting test...
2020-05-19 08:23:32,226 08:23:32.226 [main] INFO (CreateTokenExampleIntegrationTest.java:30) - Created token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJbnRlZ3JhdGlvblRlc3QiLCJwdXJwb3NlIjoidGVzdCIsImlzcyI6Im1lIn0.VmYsToj1PKBzJKQuXEyiKuJA-GkNVit0Ylh44dVF2UI
2020-05-19 08:23:32,273 08:23:32.273 [main] INFO (CreateTokenExampleIntegrationTest.java:36) - Header:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
2020-05-19 08:23:32,273 08:23:32.273 [main] INFO (CreateTokenExampleIntegrationTest.java:37) - Payload:
eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJbnRlZ3JhdGlvblRlc3QiLCJwdXJwb3NlIjoidGVzdCIsImlzcyI6Im1lIn0
2020-05-19 08:23:32,273 08:23:32.273 [main] INFO (CreateTokenExampleIntegrationTest.java:38) - Done.
##EDIT: This is a complete solution based on the accepted answer:
###Code:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
public class CreateTokenExampleIntegrationTest {
private static final Logger logger = LoggerFactory.getLogger(CreateTokenExampleIntegrationTest.class);
@Test
public void shouldCreateToken() {
logger.info("Starting test...");
// create the token
String key = "foobarkey";
Algorithm alg = Algorithm.HMAC256(key);
String issuer = "me";
JWTCreator.Builder jwt = JWT.create();
jwt.withIssuer(issuer);
jwt.withClaim("createdBy", "CreateTokenExampleIntegrationTest");
jwt.withClaim("purpose", "test");
jwt.withClaim("msg", "Hello World.");
String token = jwt.sign(alg);
logger.info("Created token: \n" + token);
// read the token
JWTVerifier verifier = JWT.require(alg)
.withIssuer(issuer)
.build();
DecodedJWT decoded = verifier.verify(token);
// header
String encHeader = decoded.getHeader();
String header = decode(encHeader);
logger.info("Header: \n" + encHeader + "\n" + header);
// payload
String encPayload = decoded.getPayload();
String payload = decode(encPayload);
logger.info("Payload: \n" + encPayload + "\n" + payload);
// done
logger.info("Done.");
}
public String decode(final String base64) {
return StringUtils.newStringUtf8(Base64.decodeBase64(base64));
}
}
### Output:
2020-05-19 10:13:29,146 10:13:29.146 [main] INFO (CreateTokenExampleIntegrationTest.java:21) - Starting test...
2020-05-19 10:13:30,031 10:13:30.031 [main] INFO (CreateTokenExampleIntegrationTest.java:32) - Created token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJbnRlZ3JhdGlvblRlc3QiLCJwdXJwb3NlIjoidGVzdCIsImlzcyI6Im1lIn0.VmYsToj1PKBzJKQuXEyiKuJA-GkNVit0Ylh44dVF2UI
2020-05-19 10:13:30,102 10:13:30.102 [main] INFO (CreateTokenExampleIntegrationTest.java:41) - Header:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
{"typ":"JWT","alg":"HS256"}
2020-05-19 10:13:30,103 10:13:30.103 [main] INFO (CreateTokenExampleIntegrationTest.java:45) - Payload:
eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJbnRlZ3JhdGlvblRlc3QiLCJwdXJwb3NlIjoidGVzdCIsImlzcyI6Im1lIn0
{"msg":"Hello World.","createdBy":"CreateTokenExampleIntegrationTest","purpose":"test","iss":"me"}
2020-05-19 10:13:30,103 10:13:30.103 [main] INFO (CreateTokenExampleIntegrationTest.java:47) - Done.
</details>
# 答案1
**得分**: 2
我查阅了`java-jwt`库,我认为它在输出`payload`和`header`的JSON字符串时只输出`base64`编码的内容。此外,“普通”的JSON字符串只是`JWTDecoder`构造函数中的临时本地字符串(参见[这里][1]),以及`JWTCreator`的私有不可访问字段(参见[这里][2]),这些字段从未“暴露给公众”。
因此,您要么自己解码`base64`字符串,要么通过反射访问`JWTCreator`的私有字段。但在这种情况下,我肯定会选择手动解码字符串。可以像这样实现(与`JWTDecoder` [的做法][1]相同):
```java
public String decodeToJson(final String base64){
return StringUtils.newStringUtf8(Base64.decodeBase64(base64));
}
DecodedJWT decoded = verifier.verify(token); // 在您的测试类中
final String headerJson = decodeToJson(decoded.getHeader());
final String payloadJson = decodeToJson(decoded.getPayload());
英文:
I looked through java-jwt
and I don't think that it outputs the payload
and header
JSON Strings other than base64-encoded
. Also, the "normal" JSON strings are just temporary local Strings in the cunstructor of JWTDecoder
(see here) and private inaccessible fields of JWTCreator
(see here) which never get "exposed to the public".
So you either have to decode the base64
Strings yourself or access the private Fields of JWTCreator
via Reflections. But I'd definitely choose decoding the String manually in this case. That could look like this (equal with how JWTDecoder
does it):
public String decodeToJson(final String base64){
return StringUtils.newStringUtf8(Base64.decodeBase64(base64));
}
DecodedJWT decoded = verifier.verify(token); // in your Test-Class
final String headerJson = decodeToJson(decoded.getHeader());
final String payloadJson = decodeToJson(decoded.getPayload());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论