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_jsonin moduleMain). Required actions: Calculate new column(s), Generate GUID and Construct json.Fields
"iat" (Issued At), "exp" (Expiration Time) Claim, "nbf" (Not Before) Claimare 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_headerin 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 encodein 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 samplein 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 decodein 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)