Tutorial

The Anatomy of a JSON Web Token

Draft updated on Invalid Date
    Default avatar

    By Chris on Code

    The Anatomy of a JSON Web Token

    This tutorial is out of date and no longer maintained.

    Introduction

    The API model has been used a great amount recently in applications. This has come about because applications can’t just rely on their own data anymore, for a project to fully see its potential, it must be able to have third-party applications, intermingle with other applications, and have its data easily accessible by developers.

    Think of how Facebook provides an API to grab its data (as long as you are authenticated of course). Facebook also allows third-party applications and other services to access its data. This is all done through an API.

    Now when we talk about building our own APIs, there’s always going to be the topic of how to secure our own API. We’ve talked a bit about token-based authentication, and built our own RESTful Node.js API.

    Today we’ll be looking at a standard (JSON Web Tokens) and how to create them.

    What are JSON Web Tokens?

    JSON Web Tokens (JWT), pronounced “jot”, are a standard since the information they carry is transmitted via JSON. We can read more about the draft, but that explanation isn’t the most pretty to look at.

    JSON Web Tokens work across different programming languages: JWTs work in .NET, Python, Node.js, Java, PHP, Ruby, Go, JavaScript, and Haskell. So you can see that these can be used in many different scenarios.

    JWTs are self-contained: They will carry all the information necessary within itself. This means that a JWT will be able to transmit basic information about itself, a payload (usually user information), and a signature.

    JWTs can be passed around easily: Since JWTs are self-contained, they are perfectly used inside an HTTP header when authenticating an API. You can also pass it through the URL.

    What does a JWT look like?

    A JWT is easy to identify. It is three strings separated by .

    For example:

        aaaaaaaaaa.bbbbbbbbbbb.cccccccccccc
    

    Let’s break down the 3 parts and see what each contains.

    Breaking Down a JSON Web Token

    Since there are 3 parts separated by a ., each section is created differently. We have the 3 parts which are:

    • header
    • payload
    • signature

    The header carries 2 parts:

    • declaring the type, which is JWT
    • the hashing algorithm to use (HMAC SHA256 in this case)

    Here’s an example:

        {
          "typ": "JWT",
          "alg": "HS256"
        }
    

    Now once this is base64encode, we have the first part of our JSON web token!

        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
    

    Payload

    The payload will carry the bulk of our JWT, also called the JWT Claims. This is where we will put the information that we want to transmit and other information about our token.

    There are multiple claims that we can provide. This includes registered claim names, public claim names, and private claim names.

    Registered Claims

    Claims that are not mandatory whose names are reserved for us. These include:

    • iss: The issuer of the token
    • sub: The subject of the token
    • aud: The audience of the token
    • exp: This will probably be the registered claim most often used. This will define the expiration in NumericDate value. The expiration MUST be after the current date/time.
    • nbf: Defines the time before which the JWT MUST NOT be accepted for processing
    • iat: The time the JWT was issued. Can be used to determine the age of the JWT
    • jti: Unique identifier for the JWT. Can be used to prevent the JWT from being replayed. This is helpful for a one-time use token.

    Public Claims

    These are the claims that we create ourselves like user name, information, and other important information.

    Private Claims

    A producer and consumer may agree to use claim names that are private. These are subject to collision, so use them with caution.

    Example Payload

    Our example payload has two registered claims (iss, and exp) and two public claims (name, admin).

        {
          "iss": "scotch.io",
          "exp": 1300819380,
          "name": "Chris Sevilleja",
          "admin": true
        }
    

    This will encode to:

        eyJpc3MiOiJzY290Y2guaW8iLCJleHAiOjEzMDA4MTkzODAsIm5hbWUiOiJDaHJpcyBTZXZpbGxlamEiLCJhZG1pbiI6dHJ1ZX0
    

    That will be the second part of our JSON Web Token.

    Signature

    The third and final part of our JSON Web Token is going to be the signature. This signature is made up of a hash of the following components:

    • the header
    • the payload
    • secret

    This is how we get the third part of the JWT:

        var encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
    
        HMACSHA256(encodedString, 'secret');
    

    The secret is the signature held by the server. This is the way that our server will be able to verify existing tokens and sign new ones.

    This gives us the final part of our JWT.

        03f329983b86f7d9a9f5fef85305880101d5e302afafa20154d094b229f75773
    

    Now we have our full JSON Web Token:

        eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzY290Y2guaW8iLCJleHAiOjEzMDA4MTkzODAsIm5hbWUiOiJDaHJpcyBTZXZpbGxlamEiLCJhZG1pbiI6dHJ1ZX0.03f329983b86f7d9a9f5fef85305880101d5e302afafa20154d094b229f75773
    

    Auth0 has created a great site to go through and test out how JWTs are made. You can see as you change the content on the fly, you are able to see the JWT get updated immediately. Auth0 provides great tools and they also maintain the jsonwebtoken Node package to handle creating and verifying JWTs in Node.

    Conclusion

    The JSON Web Token standard can be used across multiple languages and is quickly and easily interchangeable.

    You can use the token in a URL, POST parameter, or an HTTP header. The versatility of the JSON Web Token lets us authenticate an API quickly and easily by passing information through the token.

    Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

    Learn more about us


    About the authors
    Default avatar
    Chris on Code

    author

    Still looking for an answer?

    Ask a questionSearch for more help

    Was this helpful?
     
    Leave a comment
    

    This textbox defaults to using Markdown to format your answer.

    You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

    Try DigitalOcean for free

    Click below to sign up and get $200 of credit to try our products over 60 days!

    Sign up

    Join the Tech Talk
    Success! Thank you! Please check your email for further details.

    Please complete your information!

    Get our biweekly newsletter

    Sign up for Infrastructure as a Newsletter.

    Hollie's Hub for Good

    Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

    Become a contributor

    Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

    Welcome to the developer cloud

    DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

    Learn more
    DigitalOcean Cloud Control Panel