[Solved] What is the best way to generate a JSON Web Token (JWT)?

I want to access a service that uses JWT authentication for its API. Generating a JWT doesn’t look too difficult, it is a combination of BASE64URL encoding, and HMAC Signing. However, these things can be a finicky to get right, so I was wondering if anyone had done this in Mathematica? For instance, is it possible to use the SecuredAuthenticationKey function to do what I need?

Here is how to solve it:

https://mathematica.stackexchange.com/questions/231524

Hmmm, looks like this has not been tried before. OK, I shall dive in and report back

User Flinty over at mathematica.stackexchange.com came up with a great answer.

hmacFnew[method_, message_, key_] := 
 Module[{dkey, dmsg, opad, ipad, blocksize}, 
  blocksize = If[method === "SHA384" || method === "SHA512", 128, 64];
  {dkey, dmsg} = StringToByteArray /@ {key, message};
  If[Length[dkey] > blocksize, dkey = Hash[dkey, method, "ByteArray"]];
  dkey = Normal[dkey];
  If[Length[dkey] < blocksize, dkey = PadRight[dkey, blocksize, 0]];
  {opad, ipad} = ByteArray[BitXor[dkey, ConstantArray[#, blocksize]]] & /@ {92, 54};
  Hash[Join[opad, Hash[Join[ipad, dmsg], method, "ByteArray"]], method, "Base64Encoding"]]

urlfixb64[b64_?StringQ] := 
 StringReplace[StringSplit[b64, "="][[1]], {"+" -> "-", "/" -> "_"}]

secret = "secretkey";
header = <|"alg" -> "HS256", "typ" -> "JWT"|>;
payload = <|"loggedInAs" -> "admin", "iat" -> 1422779638|>;
headerJSON = ExportString[header, "JSON", "Compact" -> True];
payloadJSON = ExportString[payload, "JSON", "Compact" -> True];
header64 = Developer`EncodeBase64[headerJSON] // urlfixb64;
payload64 = Developer`EncodeBase64[payloadJSON] // urlfixb64;
signature = hmacFnew["SHA256", header64 ~~ "." ~~ payload64, secret] // urlfixb64;
token = header64 ~~ "." ~~ payload64 ~~ "." ~~ signature

(* result: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJsb2dnZWRJbkFzIjoiYWRtaW4iLCJpYXQiOjE0MjI3Nzk2Mzh9.gzSraSYS8EXBxLN_oWnFSRgCzcmJmMjLiuyu5CSpyHI" *)

Hi Andrew. The code above works?
Do you have the link to StackExchange reference?

Crossposted here.

Thanks Rohit. I have also updated my answer to bring everything in one place.