Precious Gemstones: Ruby-JWT

Extensions, libraries, dictionaries, modules… The old ways of defining add-ons be damned. None sound more enticing, by nature, to dive head first into than a vast ocean of…Gems! In this (planned) series, I’d like to begin going over and spotlighting several feature-rich Gems in order to expand on the finer points of the Ruby language. To come this far, still by no means fluent, has been a journey to say the least. Not gonna lie, it’s been a fairly rough transition from the more syntactically demanding JavaScript to the “developer-friendly” , liberty-taking powerhouse that is Ruby. A hope in pursuing these new and expansive Gems is to gather them into a toolbelt and equip myself better for future projects. Each of these Gems aren’t merely adding an extra step to the projects which inherit them as much as they are modifying the underlying skeleton of the idea as a whole. Some Gems provide tailored usefulness for prototypes of projects, that I find them to be quintessential cornerstones of certain development schemes. I’ll take every little bit of help I can get on this perilous journey into the land of 1’s and 0’s.

CLI for installing JWT

The first Gem in the series I want to “cut” into is called Ruby-JWT. JWT (pronounced ‘jot’ somehow… I don’t make the rules) stands for “JSON Web Token” and it is what’s is known a “proposed standard” by the Internet Engineering Task Force (IETF). Basically that means that the idea behind it has gone over extensive revisions, peer review and stands deeply in community favor as being among the established and enforceable tenants of the web. At one point, prior to its proposal in 2015, JWT made its way from being a proposal to an actual “standard” of the web. Essentially, it was internet law. Not much later, a decision was later made to annul its status, so now we’re back to simply being proposed.

JWTs allow sent and received data to carry with them unique encrypted packages of data known as “tokens”. These tokens, as well as the instance of a user itself, hold a signature that is assigned by the domain which they are attempting to access when the account is created. To use it in an example, if a user were to claim their admin clearance on a given domain, that domain’s security will attempt to locate a signature within the user’s token that matches up with the authentication server. Additionally, when a token is generated by a server for a user, it is required to be saved in local storage (or a cookie). If the required signature is located and the method of encryption (more on this in a bit) reflects on the server then the sent/requested JSON is permitted to unpack/extract its payload. Inversely, if that signature is not located, there are other protocols in place to further attempt to retrieve or allocate a signature to said user. Beyond that, the developer can choose what functionality is permitted or disallowed based on the type of signature on that user’s token. Neat stuff.

A commonly used scheme for authenticating using JWT. — source: coidca.com

Even though JWT is a (proposed) web standard, used in many different programming languages and not in any way unique to Ruby, I chose this Gem because authentication plays an extremely important role in telling a backend what data you’re looking to access. This is absolutely a feature I plan on including into my upcoming projects and surely plenty in the future. For now, I only want to touch on several key features Ruby-JWT brings to the table, and how it makes this specific functionality come to life.

JWT is dependent on two other key standards: JSON Web Signature and JSON Web Encryption. JWTs work as a sort of bonder to make these standards work more effectively in tandem. With a Rack or Rails backend prepared to handle POST or GET requests, JWT wraps the sensitive data between two other JSON objects, the meaty center of which is referred to as its “claim” or “payload”. JWTs are formatted as stringified JSON objects separated by ‘ . ’ and encoded in base64. Here’s the basic anatomy of a JWT to use when identifying one in the wild:

Headers

A sample Headers template

The “typ” is a simple indication that what follows is a JWT. “alg” for the second key lets the authentication server know which set of algorithmic encryption is being used to verify and retrieve the stored token. There are several other fields also valid here, but typ and arg are required.

Claims

A sample Claim

“iss” identifies the issuer of the JWT; The domain responsible for distributing and maintaining the security. iss makes up one of several “registered claims” that are reserved by the Gem to take in specific data in case additional logic is required here. Other fields listed here line up with either public or private claims. A private claim (“name” in the example) is a field agreed upon by both parties and typically relies on some user input. The public claim (“admin”) is a field read by the app or authentication server only and remains attached to to the user as a relationship attribute until edited.

Signature

A sample Signature template

The final, and most crucial part of a JWT is the signature that becomes imprinted onto it. Here both OpenSSL and base64 are used to first encode our hashes provided in the claim and headers sections and separate them with “ . “ before concatenating them onto one another. The hash is then made whole by using OpenSSL to provide a full encryption. The first argument taken in (“sha256”) is the algorithmic formula OpenSSL is to perform on the hash in full. Secondly, the server-side “secret” key is given to help the algorithm do its thing. And finally, the variable we used to grab our other encoded values is the last argument that goes into digesting out JWT.

And there you have it! A basic rundown of what Ruby-JWT asks for and performs for your app. There is an exhaustive amount that I have not uncovered about this wonderful Gem, but I’ve dabbled enough to understand some basic functionality. With a little time and experience I’ll undoubtedly have some more to say about this. For now I hope this shed a bit of light on a very cool piece of tech that is available to any and all Ruby developers!

A Software Engineering Student at Flatiron School

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store