I've created a Rest API based on the PHP Slim framework which uses JSON Web Tokens (JWT) to authenticate and authorize access.
To use the API the client must first authenticate themselves by sending their credentials to a special /auth/token
route which if correct, returns a digitally signed token containing a list of allowed permissions. All subsequent requests to the API require the token for authentication and authorization. This is pretty standard stuff and works well.
But now I now want to separate the /auth/token
service into its own micro-service so I can reuse it with other APIs in the future.
The problem is, how will the APIs now authenticate the JWT as they don't have access to the secret that was used to generate it?
I use the Firebase\JWT\JWT
to generate the token, which will be moved to the new auth service. And I use tuupola/slim-jwt-auth
middleware to authenticate the received token on each API.
As each API and the new auth service will be running on the same host I could maybe share the secret between them all but this feels like bad practice. Is there a better way?
JSON Web Token (JWT) is an open standard that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This guide will walk you through how to implement authentication for an API using JWTs and Passport, an authentication middleware for Node.
Usage-wise, JWTs can be easily used on multiple devices, such as mobiles and laptops. All of this makes JSON web tokens easier to work with across various platforms. All in all, JWT-based authentication is an excellent and secure way of transmitting information between multiple entities.
You can return a stateless JWT instead, with the allowed scopes and expiration. Debuggability: API keys are opaque random strings. JSON Web Tokens can be inspected.
JSON Web Tokens can be "self-issued" or be completely externalized, opening interesting scenarios as we will see below. OAuth2 Compliance: OAuth2 uses an opaque token that relies on a central storage. You can return a stateless JWT instead, with the allowed scopes and expiration.
It is better to sign JWT using private/public key (RSA or ECDSA algorithm) instead of a secret (HMAC algorithm). In that case your auth service would sign JWT with private key and other APIs would validate JWT with public key, well... you still need to distribute a public key to your APIs then, but you have options.
Depends on your architecture, you might look at:
API Gateway pattern
For microservice architecture a good practice is to use API Gateway pattern. More about gateway pattern. API Gateway can validate JWT token and then proxy requests to your services. So auth service would sign JWT token with private key, then requests to APIs would go though API Gateway. API Gateway would validate token with public key, so you would not distribute public key to all APIs behind the proxy.
With this approach your would need an API Gateway, you can look at: express-gateway, kong + jwt plugin, tyk etc, also there is much more benefits from API Gateway rather then just JWT token validation, like traffic control, analytics, logging, requests and responses transformations and so on.
Secrets management
Instead of or additionally to API Gateway you can take a look at centralised secrets management systems, like Hashi Vault. Depends on the project/team size it could be an overkill for your project.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With