Reputation: 131
Recently I've been learning about JWT.
And I was planning to adopt JWT on Next.js server with an external auth server that issues JWT access token.
At first I was thinking about this following logic (when fecthing data)
But I thought this was very inefficient.
Then I saw a blog post that says:
"JWT is better than other token-based authentication solutions because it does not make further validation requests to auth server but a microservice itself validates a token's validity"
But isn't it impossible to validate a JWT token without secret key?
If so, is it safe to store a JWT secret key inside many different microservices? (I am using dotenv to store secret key)
Upvotes: 8
Views: 13329
Reputation: 154995
Recently I've been learning about JWT. And I was planning to adopt JWT on Next.js server with an external auth server that issues JWT access token. At first I was thinking about this following logic (when fecthing data)
The saying "When your only tool is a hammer..." comes to mind.
(For clarity, I've tweaked your event-sequence by adding common terms from the OAuth/OIDC specs)
- Client sends request with JWT access token (and waits for a response from RP).
- some external server (the RP) receives that request
- the RP sends the JWT access token to the auth server (IdP) that issued JWT token to validate
- the RP rejects or accepts the client's request based on the IdP's response in step 3, and completes the client's request from step 1.
But I thought this was very inefficient.
Correct, it is inefficient.
What you're describing there is back-channel communication between the RP and the IdP.
As a parenthetical: note that JWTs are not normally encrypted as none of the claims within a JWT should themselves be "secret" values (but you can encrypt JWTs if you absolutely need to); also note that if you're not the IdP then you have no control over this; also note that some schemes and systems may require JWTs to be unencrypted, but that's another question).
Some back-story on signatures in JWT:
The RP needs to be able to know it can trust the claims in the JWT came from the IdP: this is ensured by having the IdP cryptographically signing the JWT and by ensuring the RP can verify that signature somehow.
The RP can then verify the signature by either:
In a well-functioning distributed system there should be minimal dependence between systems, so the second option (delegating verification to the IdP) is undesirable, so we should prefer the first option - and that first option does not require the use of symmetric keys (which must be kept secret).
Then I saw a blog post that says "JWT is better than other token-based authentication solutions because it does not make further validation requests to auth server but a microservice itself validates a token's validity"
The truth is actually far more complicated: the article you read is an unfortunate example of someone mixing broad and specific terminology together and coming to an inaccurate (and incomplete) conclusion (especially with the implication that JWT is the only scheme that supports distributed asymmetric-cryptographic signatures, because it isn't).
But isn't it impossible to validate a JWT token without secret key? If so, is it safe to store a JWT secret key inside many different microservices? (I am using dotenv to store secret key)
No. You need to understand how asymmetric encryption works in this case; but first, remember that JWTs can be signed with many different kinds of techniques, not just asymmetric cryptographic signatures.
For simplicity, follow this flowchart:
iss
(Issuer, the IdP) and aud
(Audience, the RP) claims in the JWT correctly correspond to the IdP and RP.RS256
or ES256
) it means the JWT was signed with the IdP's (secret) private key, and the signature can be verified with the IdP's public key which the RP will need to be able to access.
https://{authority}/.well-known/openid-configuration
).nbf
(Not-Valid-Before) and exp
(Expiry) claims, and any other minimally necessary claims.
HS256
), then there's two ways to continue:
Upvotes: 15