'How can I decode JWT token in android?
I have a jwt token like this
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
How can I decode this so that I can get the payload like this
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
I have used this library , but can't find a way to do what I want
Solution 1:[1]
you should split string: If you pass the first two sections through a base 64 decoder, you'll get the following (formatting added for clarity):
header
{
"alg": "HS256",
"typ": "JWT"
}
body
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
Code example:
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");
}
}
Call method for example
JWTUtils.decoded("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ");
library reference: https://github.com/jwtk/jjwt
jwt test: https://jwt.io/
Solution 2:[2]
I used a third party library named JWTDecode.Android https://github.com/auth0/JWTDecode.Android . The documentation is reasonably good . From your question , The sub , name etc are a part of the body and are called Claims . You could get them like this using the above library :
JWT parsedJWT = new JWT(jwtToken);
Claim subscriptionMetaData = parsedJWT.getClaim("name");
String parsedValue = subscriptionMetaData.asString();
Solution 3:[3]
This works using Java 8's Base64 class:
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;
}
Solution 4:[4]
If the project is already using AWSCognito SDK then CognitoJWTParser class can be used.
It has static methods getHeader(), getPayload(), getSignature().
Solution 5:[5]
I've used in a Java web application and the code will look something like below :-
Jwts.parser().setSigningKey('secret-key').parseClaimsJws(token).getBody()
It will return claims which contains the required values.
Solution 6:[6]
Based partially on the code provided by Brad Parks, adapted for use with lower versions of Android by using Apache Commons and converted to Kotlin:
In build.gradle:
implementation 'apache-codec:commons-codec:1.2'
In a Kotlin class:
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)
}
Solution 7:[7]
A no dependency version in Kotlin with Android SDK 26+ (Oreo):
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"
}
}
Solution 8:[8]
If you are using the library io.jsonwebtoken.Jwts, then use the following snippet. It works for me.
try {
val claims: Claims =
Jwts.parser().setSigningKey(secretKey.toByteArray()).parseClaimsJws(token).body
return ConnectionClaim(claims["uid"].toString(), claims["key"].toString())
} catch (e: JwtException) {
e.printStackTrace()
}
Solution 9:[9]
this code convert JWT to String and work on any API
public static String getDecodedJwt(String jwt)
{
StringBuilder result = new StringBuilder();
String[] parts = jwt.split("[.]");
try
{
int index = 0;
for(String part: parts)
{
if (index >= 2)
break;
index++;
byte[] decodedBytes = Base64.decode(part.getBytes("UTF-8"), Base64.URL_SAFE);
result.append(new String(decodedBytes, "UTF-8"));
}
}
catch(Exception e)
{
throw new RuntimeException("Couldnt decode jwt", e);
}
return result.toString();
}
Example :
JWTUtils.getDecodedJwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c")
And finally the resulting conversion
{"alg":"HS256","typ":"JWT"}{"sub":"1234567890","name":"John Doe","iat":1516239022}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | diptia |
| Solution 3 | Brad Parks |
| Solution 4 | adiga |
| Solution 5 | Apollo |
| Solution 6 | omniuni |
| Solution 7 | Anonsage |
| Solution 8 | PrimeSquid |
| Solution 9 | Pouria Hemati |
