CodeSamplez.com

Programming, Web development, Cloud Technologies

  • Facebook
  • Google+
  • RSS
  • Twitter
  • 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
Home Development Building Auth With JWT – Part 1

Building Auth With JWT – Part 1

Rana Ahsan March 30, 2020 Leave a Comment


 Building Auth With JWT – Part 1    

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 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 am going to explain the auth problem we were trying to solve, the architectural decisions we made, and our execution approach.

When you plan to buy machines to work on the garden like for example the best pole hedge trimmer there are a lot of things that you have to research to get the right one.

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 was 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 a crucial features (Gradebook). And we were building this to split into its own service as one of our first independent service candidate.

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, maybe 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 some 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 will 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 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 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 of time 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 be injecting a fairly good amount of roles/authorization info in those tokens. (depending on the user’s limit).

I will re-visit some of these in my future article around challenges/lessons learned.

To give an idea, 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:

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 required 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 avoiding 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.

Related

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

About Rana Ahsan

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

Leave a Reply Cancel reply

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

Email Subscription

Never miss any programming tutorial again.

Popular Tutorials

  • How To Work With JSON In Node.js / JavaScript
  • PHP HTML5 Video Streaming Tutorial
  • How To Work With C# Serial Port Communication
  • LinQ Query With Like Operator
  • Facebook C# API Tutorials
  • LinQ To SQL Database Update Operations In C#
  • Tutorial On Uploading File With CodeIgniter Framework / PHP
  • Utilizing Config File In C#.NET Application
  • Using Supervisord Web Interface And Plugin
  • Using GIT Plugin For Netbeans IDE

Recent Tutorials

  • Building Auth With JWT – Part 1
  • Document Your REST API Like A Pro
  • Understanding Golang Error Handling
  • Web Application Case Studies You Must Read
  • Getting Started With Golang Unit Testing
  • Getting Started With Big Data Analytics Pipeline
  • NodeJS Tips And Tricks For Beginners
  • Apple Push Notification Backend In NodeJS
  • Web Based Universal Language Translator, Voice/Text Messaging App
  • How To Dockerize A Multi-Container App From Scratch

Recent Comments

  • S. Chalisque on PHP HTML5 Video Streaming Tutorial
  • Armorik on Generate HTTP Requests using c#
  • iswaps on PHP HTML5 Video Streaming Tutorial
  • TAKONDWA on PHP HTML5 Video Streaming Tutorial
  • rorenzo on PHP HTML5 Video Streaming Tutorial

Archives

Resources

  • CodeSamplez.com Demo

Tags

.net apache api audio aws c# cache cloud server codeigniter deployment doctrine facebook git github golang htaccess html5 http image java javascript linq mysql nodejs oop performance php phpmyadmin plugin process python regular expression scalability server smarty ssh tfs thread tips ubuntu unit-test utility web application wordpress wpf

Copyright © 2010 - 2022 · CodeSamplez.com ·

Copyright © 2022 · Streamline Pro Theme on Genesis Framework · WordPress · Log in