Java 如何在android中解码JWT令牌?
我有一个这样的令牌Java 如何在android中解码JWT令牌?,java,android,jwt,Java,Android,Jwt,我有一个这样的令牌 eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ { "sub": "1234567890", "name": "John Doe", "admin": true } 我如何解码它,这样我就能得到这样的有效载荷 e
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
我如何解码它,这样我就能得到这样的有效载荷
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
我已经使用了library,但是找不到一种方法来实现我想要的功能,我已经在Java web应用程序中使用过,代码如下所示:-
Jwts.parser().setSigningKey('secret-key').parseClaimsJws(token).getBody()
它将返回包含所需值的声明。您应该拆分字符串:
如果通过base 64解码器传递前两个部分,将获得以下内容(为清晰起见添加了格式):
标题
{
"alg": "HS256",
"typ": "JWT"
}
身体
代码示例:
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");
图书馆参考资料:
jwt测试:
我使用了一个名为JWTDecode.Android的第三方库。文件相当好。根据您的问题,子项、名称等是主体的一部分,称为索赔。您可以使用上面的库获取它们:
JWT parsedJWT = new JWT(jwtToken);
Claim subscriptionMetaData = parsedJWT.getClaim("name");
String parsedValue = subscriptionMetaData.asString();
这使用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;
}
如果项目已经在使用awscognitosdk,那么可以使用
CognitoJWTParser
类。
它有静态方法getHeader()
,getPayload()
,getSignature()
部分基于提供的代码,通过使用并转换为Kotlin,适用于较低版本的Android: 在
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)
}
token(token:String):String{
val tokenParts:Array=token.split(“.”).toTypedArray()
if(tokenParts.isEmpty())返回令牌
var decodedString=“”
for(部分:标记部分中的字符串){
val partByteArray:ByteArray=
stringToFullBase64EncodedLength(部分).toByteArray(字符集.US_ASCII)
val decodedPart=String(Base64.decodeBase64(partByteArray))
decodedString+=decodedPart
//OAuth令牌中最多有两个部分,
//和数组的索引为0,因此如果索引为1
//我们已经处理了第二部分,应该中断。
如果(部分)==1)中断
}
返回解码字符串
}
private fun stringToFullBase64EncodedLength(字符串:字符串):字符串{
//正确的base64编码字符串必须可以被4整除
//我们将在不丢失数据的情况下将其填充到4的最接近倍数:
val targetLength:Int=(4*ceil(string.length.toDouble()/4)).toInt()
//现在,我们得到差异,并将其与保留字符(`=`)相加
//到字符串的结尾。稍后将删除它。
val requiredPadding:Int=targetLength-string.length
返回字符串+“=”。重复(需要填充)
}
Kotlin中使用Android SDK 26+(Oreo)的无依赖版本:
jwt(jwt:String):String{
if(Build.VERSION.SDK_INT
问题在于,is仅在API26@angryITguy不应该这样。因为不同库的其他答案也是正确的。这个图书馆使它更容易。