如何使用java-jwt从JWT令牌中获取头部/负载的JSON字符串

huangapple go评论67阅读模式
英文:

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&#39;m not seeing this method (there are individual getters for individual pieces of the message but I&#39;m not seeing anything that returns the complete message as a JSON string).  

The getHeader() and getHeader() methods return the encoded strings.  I&#39;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&#39;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(&quot;Starting test...&quot;);
    		// create the token
    		String key = &quot;foobarkey&quot;;
    		Algorithm alg = Algorithm.HMAC256(key);
    		String issuer = &quot;me&quot;;
    		JWTCreator.Builder jwt = JWT.create();
    		jwt.withIssuer(issuer);
    		jwt.withClaim(&quot;createdBy&quot;, &quot;CreateTokenExampleIntegrationTest&quot;);
    		jwt.withClaim(&quot;purpose&quot;, &quot;test&quot;);
    		jwt.withClaim(&quot;msg&quot;, &quot;Hello World.&quot;);
    		String token = jwt.sign(alg);
    		logger.info(&quot;Created token: \n&quot; + token);
    		// read the token
    		JWTVerifier verifier = JWT.require(alg)
    				.withIssuer(issuer)
    				.build();
    		DecodedJWT decoded = verifier.verify(token);
    		logger.info(&quot;Header: \n&quot; + decoded.getHeader());
    		logger.info(&quot;Payload: \n&quot; + decoded.getPayload());
    		logger.info(&quot;Done.&quot;);
    	}
    
    }

And here&#39;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(&quot;Starting test...&quot;);
    		// create the token
    		String key = &quot;foobarkey&quot;;
    		Algorithm alg = Algorithm.HMAC256(key);
    		String issuer = &quot;me&quot;;
    		JWTCreator.Builder jwt = JWT.create();
    		jwt.withIssuer(issuer);
    		jwt.withClaim(&quot;createdBy&quot;, &quot;CreateTokenExampleIntegrationTest&quot;);
    		jwt.withClaim(&quot;purpose&quot;, &quot;test&quot;);
    		jwt.withClaim(&quot;msg&quot;, &quot;Hello World.&quot;);
    		String token = jwt.sign(alg);
    		logger.info(&quot;Created token: \n&quot; + 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(&quot;Header: \n&quot; + encHeader + &quot;\n&quot; + header);
    		// payload
    		String encPayload = decoded.getPayload();
    		String payload = decode(encPayload);
    		logger.info(&quot;Payload: \n&quot; + encPayload + &quot;\n&quot; + payload);
    		// done
    		logger.info(&quot;Done.&quot;);
    	}
    
    	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
    {&quot;typ&quot;:&quot;JWT&quot;,&quot;alg&quot;:&quot;HS256&quot;}
    2020-05-19 10:13:30,103 10:13:30.103 [main] INFO  (CreateTokenExampleIntegrationTest.java:45) - Payload: 
    eyJtc2ciOiJIZWxsbyBXb3JsZC4iLCJjcmVhdGVkQnkiOiJDcmVhdGVUb2tlbkV4YW1wbGVJbnRlZ3JhdGlvblRlc3QiLCJwdXJwb3NlIjoidGVzdCIsImlzcyI6Im1lIn0
    {&quot;msg&quot;:&quot;Hello World.&quot;,&quot;createdBy&quot;:&quot;CreateTokenExampleIntegrationTest&quot;,&quot;purpose&quot;:&quot;test&quot;,&quot;iss&quot;:&quot;me&quot;}
    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());

huangapple
  • 本文由 发表于 2020年5月19日 20:27:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/61891066.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定