With EasyMorph it’s possible to easily build and verify JWT tokens signed by using HS256, HS384 and HS512 algorithms. JSON Web Token (JWT) (RFC 7519) is a compact, URL-safe means of representing claims to be transferred between two parties.
Prerequisites:
EasyMorph v 4.4.1 or later
This short article has an attachment with sample code. Any mention of table names or modules are related to this code.
-
First, create a JWT payload. (Table
payload_json
in moduleMain
). Required actions: Calculate new column(s), Generate GUID and Construct json.Fields
"iat" (Issued At), "exp" (Expiration Time) Claim, "nbf" (Not Before) Claim
are unix timestaps (RFC NumericDate). EasyMorph has built-in functions to work with dates. But there is no function like tounixtime, we’ll need to perform some date calculations (in extended syntax).// "exp" (Expiration Time) = token expiration is in 1 hour from now let expiration_utc_time = utctime(addhours(now(),1)) let unixtimedelta_in_days = expiration_utc_time - fromunixtime(0) // convert time delta from days to seconds (unix timestamp) floor(unixtimedelta_in_days * 24*60*60)
Sample output for JWT payload
{"iss":"issuer@site.com","sub":"issuer@site.com","iat":1599481688,"exp":1599485288,"jti":"df3681bc-3d07-4682-9e58-f463cdcd3381","name":"User name","nbf":1599481688,"role":["Admin","Manager"]}
-
Construct JWT header (Table
json_header
in moduleencode jwt
).
Required actions: Calculate new column(s) and Construct json.Sample output
{"alg":"HS256","typ":"JWT"}
-
Encode and sign JWT header and JWT payload. (Table
JTW encode
in moduleencode jwt
)
Header and payload must be encoded into base64url (a special url safe type of base64). Result of encoding need to be concatenated via dot (.
).let encoded_data = encode('Base64url',[header]) & '.' & encode('Base64url',[json_payload])
Then sign encoded_data
with secret key. For HS256 HS384 HS512
algorithms just use appropriate HMAC
function with required secret_key
. Since hmachex
generates hex, the result must be converted from hex to base64url via hexdecode
.
let hash_alg =
if {alg} = 'HS256' then 'SHA256' else
if {alg} = 'HS384' then 'SHA384' else
if {alg} = 'HS512' then 'SHA512' else
'<not supported>'
let signature = hexdecode('base64url', hmachex(hash_alg,encoded_data,{secret_key}))
The final encoded and signed JWT token composed via expression
encoded_data & '.' & signature
and looks like a very long string
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJpc3N1ZXJAc2l0ZS5jb20iLCJzdWIiOiJpc3N1ZXJAc2l0ZS5jb20iLCJpYXQiOjE1OTk0ODc0MjMsImV4cCI6MTU5OTQ5MTAyMywianRpIjoiNjcyOGU1MGYtOTM2My00MzQwLWI2Y2UtYjc0OWI3ZTliMWYxIiwibmFtZSI6IlVzZXIgbmFtZSIsIm5iZiI6MTU5OTQ4NzQyMywicm9sZSI6WyJBZG1pbiIsIk1hbmFnZXIiXX0.yC78OEs8YIRc21mtPbQK7YQ_bqcZ5fbKId-GYUGjTYU
-
Passing a JWT token to the web service (Table
Create JWT sample
in moduleMain
)
Generated JWT Token can be passed to the web service by using Iterate Web request action. First, create a column with header value like'Bearer ' & [JWT]
and then bind this column to headerAuthorization
. -
Verifying and decoding JWT (Table
JWT decode
in moduledecode jwt
)
Verification is done by signature validation and expiration time checking. Other fields, likenbf, iss
, are not validated by this code, so you need to do this manually (if required). If JTW token is valid, module will return a json payload.
JWT encode_decode.morph (26.6 KB)