Use JWT to authenticate separate API Microservice

10,206

Solution 1

One common pattern here would be to use an API gateway as the entry point to your entire microservice architecture. Incoming requests for authentication would be routed to the appropriate microservice. If the credentials provided be correct, a new JWT would be returned to the gateway, which would then forward to the caller. For the actual microservice APIs which comprise your application, the gateway would check that the incoming JWT be valid before allowing the request to hit the microservice.

This answer leaves out a few things, for simplicity. For instance, often you would want to have an authorization microservice, which decides what a user is allowed to do. Also, implementing JWT can be involved. You might need a cache layer to keep track of whitelisted and/or blacklisted JWT.

Solution 2

You could write a library that you import into your other microservices that requires all routes by default to require authentication. This library could have a mechanism to validate JWT's at the microservice level, so you never need to talk to your auth api to see if a JWT is valid or not. See the description and diagram below:

Your auth server will will need to be the single issuer of JWTs to your microservices. So, when a user logs in and successfully authenticates, your auth server will issue a JWT signed with a private key (signing MUST be asymmetric - RS256 is one example) you keep on the auth server only; do not give this private key to other microservices that you wish to validate JWTs inside of. What you can do is derive a public key based on the private key you sign your tokens with and publish that to an endpoint on your auth server that requires no authentication - the public key will be represented in the form of a JWK (see link to spec). Google does something similar here. Then, in each of your microservices, your library will need to devise a way to make a GET request to the public key endpoint on your auth server every X minutes to see if there are any changes and cache the public key in each microservice. By having the public key cached in your microservice, you will be able to validate the requesting JWT inside the service that is being requested.

Then whenever a request comes into one of your microservices, the library you import will examine the requesting JWT, check its validity, and grant access/authorization if the token is valid. The beauty of using a private/public key pair and asymmetric key signing is that you can validate a token based on the public key alone, but not sign it. So as long as each service has the public key from your /cert endpoint, they can validate a token without ever needing to talk to the auth server or knowing the private key.

This will require a little more work up front, but will yield you massive amount of ease, flexibility, and peace of mind in the future knowing only one source knows your private key.

enter image description here

Share:
10,206
Luke
Author by

Luke

I'm a regular "techie", by day I'm a DevOps Engineer for a corporate e-learning company, by night I'm a hobbyist coder currently learning web development with Node, React and Redux along with Python and Ruby on Rails. I've written a few small in-house projects for work but I'm currently working on one that I hope to Open Source and start a community of like-minded coders around it!

Updated on June 13, 2022

Comments

  • Luke
    Luke almost 2 years

    I am developing an app using microservices in NodeJS. I have built an auth api which handles the usual registration login etc and it issues JWT's

    How do I use these to protect routes in a separate API microservice written with Express?

    Do I need to use JWT with the secret to decrypt the token in the API app?

  • html_programmer
    html_programmer over 4 years
    Disadvantage of this sort of common library, is that any changes to the library cause all microservices needing to pull the upgrades + redeployed. This is not needed when you just call an auth micro-service.
  • Dhwanil Patel
    Dhwanil Patel over 4 years
    @Chappie Johnson can you please provide some link or demo project which describe same flow well manner?
  • Marco Prins
    Marco Prins over 3 years
    Easy if all your microservices use the same backend language, but a lot of work if they don't. Usually it's desirable to leverage the best language for each service, that's one of the nice things about microservices
  • Shankar Regmi
    Shankar Regmi almost 3 years
    Wouldn't it cause a bottleneck in a single API gateway?