In the body of a request, a user needs to prove their auth with a JWT, Cookie or something similar.
Individual services rely on a central auth service.
A microservice after receiving a request will need to check with an authentication service.
Sync Request in microservices is a request directly to a auth service.
Similar to the first, however the authentication service comes through a central gateway.
You teach each service how to decide whether a user is authenticated.
You teach the service how to inspect the JWT/Cookie and decide if the user is authenticated.
The downside to this method is that authentication method is that communicating between microservices becomes difficult.
The issue would be how to let individual services that handle their own auth known when auth tokens (JWTs, Cookies, etc.) are no longer valid.
You can get around this by only ensure that a JWT is only good for however minutes. You can use an event bus to head around to all of services to ensure their access is short-lived.
They are a transport mechanism.
The flow goes:
Set-Cookie
header with a particular value.An authentication/authorization mechanism.
We take an arbitrary piece of information (payload) and apply it through a JWT creation algorithm.
This can be both encoded and decoded.
This JWT can now have that JWT through a few methods: as a Authorization header, a token in the body, or still set it as a Cookie.
JWTs don't require some kind of backing store.
There are some issues that pop up with JWTs and SSR.
When you are doing SSR, you must use a Cookie to communicate during the initial page load. You can work around this with service workers.
We are using cookie-session
in this example, but you nees to be careful about whether or not this encrpytion method is understood across different languages.
You need to check the encryption method.
JWTs are tamper resistent so are not encrypted in this example.
// generating a JWT const payload = { key: 'somethingAboutUser', id: 123, email: 'user@email.com' }; const userJwt = jwt.sign(payload, 'secret'); // storing on session req.session = { jwt: userJwt, };
If you head to JWT.io, you can see with a token that the information passed can be decoded. However, if you do not pass the signing key, it will not be a valid token.
// middleware for the user import jwt from 'jsonwebtoken'; export const currentUser = (req, res, next) => { if (!req.session?.jwt) { return next(); } try { const payload = jwt.verify(req.session.jwt, process.env.JWT_KEY!) req.currentUser = payload; } catch (e) { } next(); };
You never want to hardcode the secret. Based on what you are running (Kubernetes, Lambda, etc.) you will want to keep the secret stored as a secret based on your approach.
Extending types:
interface UserPayload { id: string; email: string; } declare global { namespace Express { interface Request { currentUser?: UserPayload; } } }