'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().

https://github.com/aws-amplify/aws-sdk-android/blob/master/aws-android-sdk-cognitoidentityprovider/src/main/java/com/amazonaws/mobileconnectors/cognitoidentityprovider/util/CognitoJWTParser.java

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