我有一个像这样的jwt令牌
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
如何对此进行解码,以便我可以像这样获得有效载荷
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
我使用过this库,但找不到办法做我想做的事情
答案 0 :(得分:33)
你应该拆分字符串: 如果您通过base 64解码器传递前两个部分,您将获得以下内容(为清晰起见,添加了格式):
头
{
"alg": "HS256",
"typ": "JWT"
}
体
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
代码示例:
public class JWTUtils {
public static void decoded(String JWTEncoded) throws Exception {
try {
String[] split = JWTEncoded.split("\\.");
Log.d("JWT_DECODED", "Header: " + getJson(split[0]));
Log.d("JWT_DECODED", "Body: " + getJson(split[1]));
} catch (UnsupportedEncodingException e) {
//Error
}
}
private static String getJson(String strEncoded) throws UnsupportedEncodingException{
byte[] decodedBytes = Base64.decode(strEncoded, Base64.URL_SAFE);
return new String(decodedBytes, "UTF-8");
}
}
调用方法例如
JWTUtils.decoded("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ");
库参考: https://github.com/jwtk/jjwt
jwt测试: https://jwt.io/
答案 1 :(得分:3)
我使用了名为JWTDecode.Android https://github.com/auth0/JWTDecode.Android的第三方库。文档相当不错。根据您的问题,子,名称等是身体的一部分,称为声明。你可以使用上面的库得到它们:
JWT parsedJWT = new JWT(jwtToken);
Claim subscriptionMetaData = parsedJWT.getClaim("name");
String parsedValue = subscriptionMetaData.asString();
答案 2 :(得分:1)
我在Java Web应用程序中使用过,代码如下所示: -
Jwts.parser().setSigningKey('secret-key').parseClaimsJws(token).getBody()
它将返回包含所需值的声明。
答案 3 :(得分:0)
这可以使用Java 8的Base64类:
public String getDecodedJwt(String jwt)
{
String result = "";
String[] parts = jwt.split("[.]");
try
{
int index = 0;
for(String part: parts)
{
if (index >= 2)
break;
index++;
byte[] partAsBytes = part.getBytes("UTF-8");
String decodedPart = new String(java.util.Base64.getUrlDecoder().decode(partAsBytes), "UTF-8");
result += decodedPart;
}
}
catch(Exception e)
{
throw new RuntimeException("Couldnt decode jwt", e);
}
return result;
}
答案 4 :(得分:0)
如果项目已经在使用AWSCognito SDK,则可以使用CognitoJWTParser
类。
它具有静态方法getHeader()
,getPayload()
,getSignature()
。
答案 5 :(得分:0)
部分基于Brad Parks提供的代码,通过使用Apache Commons使其适用于较低版本的Android,并转换为Kotlin:
在build.gradle
中:
implementation 'apache-codec:commons-codec:1.2'
在Kotlin课堂上:
fun decodeToken(token: String): String{
val tokenParts: Array<String> = token.split(".").toTypedArray()
if(tokenParts.isEmpty()) return token
var decodedString = ""
for(part: String in tokenParts){
val partByteArray: ByteArray =
stringToFullBase64EncodedLength(part).toByteArray(Charsets.US_ASCII)
val decodedPart = String(Base64.decodeBase64(partByteArray))
decodedString+=decodedPart
// There are a maximum of two parts in an OAuth token,
// and arrays are 0-indexed, so if the index is 1
// we have processed the second part and should break.
if(tokenParts.indexOf(part) == 1) break
}
return decodedString
}
private fun stringToFullBase64EncodedLength(string: String): String{
// A properly base64 encoded string must be divisible by 4
// We'll pad it to the nearest multiple of 4 without losing data:
val targetLength: Int = ( 4 * ceil( string.length.toDouble()/4 ) ).toInt()
// Now, we get the difference, and add it with a reserved character (`=`)
// to the end of the string. It will get removed later.
val requiredPadding: Int = targetLength-string.length
return string+"=".repeat(requiredPadding)
}
答案 6 :(得分:0)
Android SDK 26+ (Oreo) 的 Kotlin 无依赖版本:
fun extractJwt(jwt: String): String {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return "Requires SDK 26"
val parts = jwt.split(".")
return try {
val charset = charset("UTF-8")
val header = String(Base64.getUrlDecoder().decode(parts[0].toByteArray(charset)), charset)
val payload = String(Base64.getUrlDecoder().decode(parts[1].toByteArray(charset)), charset)
"$header\n$payload"
} catch (e: Exception) {
"Error parsing JWT: $e"
}
}