• Skip to main content
  • Skip to primary sidebar
  • Skip to footer
  • Home
  • Featured
    • C# Tutorials
      • LinQ Tutorials
      • Facebook C# API Tutorials
    • PHP Tutorials
      • CodeIgniter Tutorials
    • Amazon AWS Tutorials
  • Categories
    • Programming
    • Development
    • Database
    • Web Server
    • Source Control
    • Management
    • Project
  • About
  • Write
  • Contact

CodeSamplez.com

Programming, Web development, Cloud Technologies

You are here: Home / Development / Building Auth With JWT – Part 1

Building Auth With JWT – Part 1

March 30, 2020 by Rana Ahsan Leave a Comment

Auth With JWT

TLDR; JWT(JSON Web Token) can be a very easy yet effective way to build an auth platform(authentication and authorization).

In one of my past employments, I was fortunate enough to be part of an interesting yet technically challenging project, that aimed to solve the auth problem(authentication+authorization) in a distributed service-oriented architecture(I am referring to this as service-oriented instead of microservice as it started in that way and still had a way to go to establish a microservice infrastructure).

In this post, I will explain the auth problem we were trying to solve, the architectural decisions we made, and our execution approach.

Problems we were solving:

Engineering Problem:

At that point in time, as an engineering organization, we were still using monolithic architecture. Naturally, we were growing as a startup and started to feel the pains of the monolith(slow deployment pipeline, tight and/or wrong coupling between components, slower developer productivity etc) and were thriving as a team to move towards a distributed microservice architecture. Some example components which were some great candidates to be in their separate services (It was an ed-tech platform):

  • Payment
  • Gradebook
  • Lecture

However, to achieve this, there is another core problem we would have to solve. Which is to support authentication/authorization in a distributed service-oriented architectural set-up. The authentication problem was critical as we started building crucial features such as Gradebook, which would split into its own service as one of our first independent service candidates.

Fig: Some candidates to be split from monolith to independent service

Product problems:

As a startup, we were growing our product line and had a couple of specific business problems we needed to solve with our users:

Support new roles:

Our platform only had a few different roles defined from the very early stage of the company, like:

  • Teacher
  • Student
  • Anonymous
  • Superuser

We were in need of introducing a few new roles, like:

  1. TA(Teaching Assistant)
  2. School Admin

Context-based roles:

Just introducing new roles was not enough. We also needed to make those roles context-based. For example, a user, who is a student in one course, may be assigned as TA in another course. Teachers sometimes also want to preview how a student experience looks like for their students, which is, being a student in certain courses for a short period of time.

The approach to building the auth platform: 

Making the core technology decision:

First and foremost, we had to pick the core technology that would be relying upon to build this auth platform. We had a bunch of different options to pick from:

  • Third-party auth provider: Like Auth0, Okta, AWS Cognito etc.
  • Build our own auth service.
  • Use a token-based solution that doesn’t require a separate service to manage.

Finally, we settled down on the token(JWT) based solution. Some of the key reasons for that:

  • The cost was the major factor that caused us to move away from third-party solutions.
  • As we decided to build our own platform, we needed an approach that would be simple but effective.
  • We wanted to reduce service level overhead as it would introduce a central point of failure and would require some serious investment around high availability/reliability which we weren’t highly experienced with as an engineering organization just yet.

Also, as a side note, I will highly recommend using a decision matrix to help with such a scenario where you have multiple paths and trying to decide on one that fits your criteria.

Approaching auth with JWT:

After the core technology decision, the next problem was to settle down on the approach we would take to build the auth platform using JWT. As a result of this, some fundamental considerations we need to make:

  • Shortlived Tokens: The tokens needed to be shortlived, as, by design, JWT tokens can be inspected by any third party. To guard against a phishing attack, the JSON payload is encoded(base 64) and signed by a secret key shared by all the services so that a service can validate its issued by a trusted source. These tokens are usually valid for a very short period and the client would need to refresh their token after it expires.
  • Client ability to force refresh the tokens: Based on how long a token can be valid before it expires, the information inside the JWT can be expired(right after a user enroll/unenroll/create a course etc) and would experience unexpected behaviours if not refreshed forcefully right after those certain use cases.
  • Token size: Token size was another fundamental consideration as we would inject a fairly good amount of roles/authorization info in those tokens. (depending on the user’s limit).

I will revisit some of these in my future article around challenges/lessons learned.

To give an idea of how a token would look like, after injecting the user’s identify+authorization info:

{
    "iss": "codesamplez.com",
    "iat": 1585529508,
    "exp": 1617065508,
    "sub": "user@codesamplez.com",
    "full_name": "John Doe",
    "roles": {
        "course": {
            "teacher": ["123", "345"]
        }
    }
}

Execution Strategy towards Auth:

This was a multi-quarters project that needed a long-term roadmap and phased delivery. These are the brief steps we followed:

  • Centralizing all authorization usages in our existing monolith.
  • Building JWT-based Solution:
    • Inject identity/authorization info inside the JWT whenever someone registers/logs in to the system.
    • Validate the user’s role in the context by looking into the JWT payload for requests that require authorizations(hint: applies to almost all traffic other than a very small number of public APIs).
  • Build a client library as the authorization abstraction that we can use as a dependency on other new services. API was quite simple as:
    • auth_lib.is_authenticated(JWT_token) – check if the client making requests with a valid JWT token.
    • auth_lib.is_authorized(user, context, cotext_id, role) – check if the user is authorized as a specified role for the given context.
  • Migration/Rollout:
    • Migrate every user’s authorization data on demand. Helped us avoid dealing with large migration pain.
    • Uninterrupted rollout: We used feature flipper flags to gatekeep this new platform so that we can disable them anytime it doesn’t work as we expect it to reduce the impact on our end users.

Wrapping up:

This is what our new architecture (except auth was still part of the monolith) afterwards:

Fig: New Service-oriented architecture with JWT.

I will try to write another article focusing on the challenges we have faced along the way, lessons learned and some fun findings throughout the journey. Stay tuned!

Also, feel free to share your thoughts in the comments below.

Share If Liked

  • Click to share on Facebook (Opens in new window)
  • Click to share on Twitter (Opens in new window)
  • Click to share on LinkedIn (Opens in new window)
  • Click to share on Pinterest (Opens in new window)
  • Click to share on Reddit (Opens in new window)
  • Click to share on Tumblr (Opens in new window)
  • Click to share on Pocket (Opens in new window)

You may also like

Filed Under: Development Tagged With: authenticatin, authorization, jwt

About Rana Ahsan

Rana is a passionate software engineer/Technology Enthusiast.
Github: ranacseruet

Reader Interactions

Leave a Reply Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Primary Sidebar

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 3,774 other subscribers

Follow Us

  • Twitter
  • Facebook

Top Posts & Pages

  • How To Work With JSON In Node.js / JavaScript
    How To Work With JSON In Node.js / JavaScript
  • PHP HTML5 Video Streaming Tutorial
    PHP HTML5 Video Streaming Tutorial
  • LinQ Query With Like Operator
    LinQ Query With Like Operator
  • How To Work With C# Serial Port Communication
    How To Work With C# Serial Port Communication
  • Getting Started With Smarty Template Engine
    Getting Started With Smarty Template Engine
  • Generate HTTP Requests using c#
    Generate HTTP Requests using c#
  • Using Supervisord Web Interface And Plugin
    Using Supervisord Web Interface And Plugin
  • Facebook C# API Tutorials
    Facebook C# API Tutorials
  • Utilizing Config File In C#.NET Application
    Utilizing Config File In C#.NET Application
  • Getting Started With UDP Programming in Java
    Getting Started With UDP Programming in Java

Recent Posts

  • Building Auth With JWT – Part 2
  • Building Auth With JWT – Part 1
  • Document Your REST API Like A Pro
  • Understanding Golang Error Handling
  • Web Application Case Studies You Must Read

Tags

.net angularjs apache api audio auth authenticatin aws c# cloud server codeigniter deployment docker doctrine facebook git github golang htaccess html5 http javascript jwt linq mysql nodejs oop performance php phpmyadmin plugin process python regular expression scalability server smarty socket.io tfs tips unit-test utility web application wordpress wpf

Footer

Archives

Follow Us

  • Twitter
  • Facebook

Subscribe to Blog via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

Join 3,774 other subscribers

Copyright © 2023