Recently, I had to use JSON Web Tokens for the first time to integrate with Zendesk's single sign-on system (SSO). JSON Web Tokens are a secure and simple way to pass data (known as claims) between web systems. Essentially, you pass a base64url-encoded JSON payload, along with a secure signature, to another system that will verity your signature (using a shared secret key) and then deserialize your data. To get this working, I created a small ColdFusion module that supports HMac-based signatures.
You can use JsonWebTokens.cfc in one of two ways. For one-off use, you can use the .encode() and .decode() methods:
- JsonWebTokens.encode( payload, secretKey [, algorithm] )
- JsonWebTokens.decode( token, secretKey [, algorithm] )
Behind the scenes, however, these methods are actually instantiating a JsonWebTokensClient.cfc component for one-off use. If you intend to use the same signing key and hashing algorithm multiple times during the life-cycle of your application, it would be more efficient to just instantiate and cache a client instance:
- JsonWebTokens.createClient( secretKey [, algorithm] )
This will create a JSONWebTokenClient.cfc with the stored key and algorithm. This component also exposes an .encode() and .decode() method, but only requires the payload and token, respectively, as the key and algorithm are encapsulated:
- JsonWebTokensClient.encode( payload )
- JsonWebTokensClient.decode( token )
This is particularly helpful if you want to configure your JsonWebTokensClient implementation during application bootstrap and then inject it into other components without having to worry about passing around your secret key.
More than anything, this was just an excuse for me to think about object design and how different behaviors can be swapped in an out. For example, the client depends on two different encoders: one for the Base64url standard and one for the JSON standard. If you wanted to manually assemble a Client, you could swap in your own implementation. So, if you fell victim to the serializeJson() bug and \u-encodings, you could swap out the JSON-encoder with something "safer."