Separate authorization and authentication across microservices
Sometimes you may need to separate authorization and authentication in NestJS.
Separation of concerns
Let’s consider this scenario.
We want to build a system based on microservices and all of the services are built using NestJS.
The services are split across domains. We also have a Gateway which act as the entry point for the system and it takes care of authentication.
NestJS uses PassportJS for authentication. PassportJS has the concept of strategy which simplifies different authentication protocols/methods.
Here, we use JWT based token validation based on OAuth2. We provide the necessary configuration to the constructor of PassportStrategy
In NestJS, authorization happens via Guard. Here, we create the simple guard which authorized the requestor based on a claim called scope in jwt token.
You can definitely decode the jwt token within the Guard. But, I like to separate it into a separate class. This AuthorizationStrategy simply decodes token and is added into the request.user object by the use of PassportStrategy.
import{Injectable}from'@nestjs/common';import{ConfigService}from'@nestjs/config';import{PassportStrategy}from'@nestjs/passport';import{ExtractJwt,Strategy}from'passport-jwt'import{passportJwtSecret}from'jwks-rsa';import{IdentityProviderConfig}from'../../configuration';@Injectable()import{BadRequestException,Injectable}from'@nestjs/common';import{PassportStrategy}from'@nestjs/passport';import{Strategy}from'passport-custom';import*asjwtfrom'jsonwebtoken';@Injectable()exportclassAuthorizationStrategyextendsPassportStrategy(Strategy,'authz',){asyncvalidate(req: Request){constheader=req.headers['authorization'];consttoken=header.slice(7);if(!token){thrownewBadRequestException('There is no access token in header');}constdecoded=jwt.decode(token);returndecoded;// this decoded token can be accessed from request.user in Guard
}}