I want to decode a simple JWT Token in Delphi XE5, but when I do it as shown below, the decodedPayload is missing the final } of the JSON object.
What am I doing wrong?
function getIssuerFromToken(token: string): string;
var
tokenPayload, decodedTokenPayload, issuer: string;
tokenJSONValue: TJSONValue;
tokenJSONWrapper: TKJSONWrapper;
tokenPayloadStartIndex, tokenPayloadEndIndex, tokenPayLoadLength: integer;
begin
tokenPayloadStartIndex := Pos('.', token) + 1;
tokenPayloadEndIndex := Pos('.', token, tokenPayloadStartIndex);
tokenPayLoadLength := tokenPayloadEndIndex - tokenPayloadStartIndex;
tokenPayload := Copy(token, tokenPayloadStartIndex, tokenPayLoadLength);
decodedTokenPayload := TIdDecoderMIME.DecodeString(tokenPayload);
...
Per RFC 7519 for the JSON Web Token spec, a JWT token consists of base64url-encoded parts separated by periods. The base64url encoding is described in RFC 7515 for the JSON Web Signature spec. And according to that spec, the base64 is NOT padded:
Since base64 requires the input to be an even multiple of 4 characters, you need to add padding to the base64 data before you decode it. You also need to url-decode the base64 before decoding, too. RFC 7515 even provides an example implementation in Appendix C:
In addition, the JSON that is inside the base64 must be UTF-8 encoded, so you have to account for that as well while decoding the base64. The default byte encoding used by
TIdDecoderMIMEis 8-bit not UTF-8, but itsDecodeString()method does have an optionalAByteEncodingparameter so you can specify UTF-8.So, try something like the following in your code: