JSON Web Token Helper
The JSON Web Token Helper contains handlers which allows you to generate, decode and verify JSON Web Tokens. It follows the industry standard RFC 7519 which is a means for representing claims as a JSON object to be transferred between two parties. The JWT helper uses the HMAC SHA256, SHA384 or SHA512 hashing algorithm to sign tokens, RSA public/private key pairs are currently not supported. If you are not familiar with JSON Web Tokens you can read about the concept at https://jwt.io.
Note: This helper requires server engine 8 or higher and the LiveCode Builder (library) extension com.livecode.library.json which needs to be stored in application/extensions. So, the path to the extension is application/extensions/com.livecode.library.json/module.lcm. Please read about how to include/load the LiveCode JSON extension in chapter "Extensions".
Note: HMAC SHA384 and SHA512 hashing algorithms are not supported on LiveCode server prior to version 9.
Loading this Helper
This helper is loaded using the following code:
The key (secret) used to sign the token should be saved to a file named "jwt.lc" in system/application/config. Preferably this key is a binary string which implicitly needs to be base64 encoded. If you don't specify a key it will be generated for you using the LiveCode randomBytes(64) function and saved to system/application/config/jwt.lc on calling the handler to encode a token. Keep in mind that if your server is not totally under your control it's impossible to ensure key security so you may want to think carefully before using it for anything that requires high security.
The following handlers are available:
rigJWTencode(pHeader, pPayload, pNumBits)
This function generates and returns a JSON Web Token. The first parameter which is used to build the header object is optional and is generated automatically if not defined. Usually you can leave this parameter empty or else it needs to be a comma delimited key value list or an array. The header generated by revIgniter consists of the type of the token, which is "JWT" and the appropriate hashing algorithm ("HS256" on LiveCode below version 9, otherwise the algorithm is determined by the value of the third optional parameter). Like the first parameter the mandatory second parameter can be a comma delimited key value list or an array. The optional third parameter is used to determine the hashing algorithm. Valid values are "256", "384", "512" or empty. If the parameter is empty the default value on LiveCode server below version 9 is "256", otherwise "512" is used. Example using HS256 on LIveCode server below vesion 9 and HS512 on LiveCode server version 9 or higher:
put the seconds into tIAT put tIAT + 10 into tNBF put tIAT + 60 into tEXP put uuid() into tJTI put "sub, jwt test, name," && tUsername & ", admin, true, iat," && tIAT & ", nbf," \ && tNBF & ", exp," && tEXP & ", jti," && tJTI into tJWTpayload put rigJWTencode( , tJWTpayload) into tJWT put tJWT into tTokenA["jwt"] rigSetHeader "Content-type: application/json" put JsonExport(tTokenA)
Following a variant using an array as second parameter:
put the seconds into tIAT put tIAT + 10 into tNBF put tIAT + 60 into tEXP -- Note: Seconds need to be a string, otherwise the data of JsonExport is not valid. put tIAT & "" into tJWTpayloadA["iat"] put tNBF & "" into tJWTpayloadA["nbf"] put tEXP & "" into tJWTpayloadA["exp"] put "jwt test" into tJWTpayloadA["sub"] put tUsername into tJWTpayloadA["name"] put "true" into tJWTpayloadA["admin"] put uuid() into tJWTpayloadA["jti"] put rigJWTencode( , tJWTpayloadA) into tJWT put tJWT into tTokenA["jwt"] rigSetHeader "Content-type: application/json" put JsonExport(tTokenA)
These two samples above assume that the client side provides code which handles the response in form of a JSON object.
Decode and validate a JSON Web Token. The parameter representing a token is optional. If not provided the function assumes that the client side has sent the JWT in an "Authorization" header using the "Bearer" schema (Authorization: Bearer <token>). The optional second parameter is used to determine the hashing algorithm. Valid values are "256", "384", "512" or empty. If the parameter is empty the default value on LiveCode server below version 9 is "256", otherwise "512" is used. Example using HS256 on LIveCode server below vesion 9 and HS512 on LiveCode server version 9 or higher:
put "The secret data." into tSecretData put rigJWTdecode() into tJWTA put the seconds into tCurrentTime put TRUE into tTimeValid if tCurrentTime < tJWTA["payload"]["nbf"] then put "Token not yet valid." into tA["responsedata"] put FALSE into tTimeValid else if tCurrentTime > tJWTA["payload"]["exp"] then put "Token expired." into tA["responsedata"] put FALSE into tTimeValid end if if tTimeValid is TRUE then if tJWTA["valid"] then put tSecretData into tA["responsedata"] else put tJWTA["response"] into tA["responsedata"] end if end if rigSetHeader "Content-type: application/json" put JsonExport(tA)
The sample above assumes that the client side provides code which handles the response in form of a JSON object.
This function returns an array including the following keys:
(the value is the token header as array)
(the value is the token payload as array)
(the value is a boolean, this refers to the integrity of the token)
(the value is empty in case the token is valid, otherwise it is a string "HTTP/1.0 401 Unauthorized", in case the token can not be decoded the string is "HTTP/1.0 400 Bad Request" - use these strings as response header if something went wrong and the integrity of the token could not be determined)