Reputation: 1477
I have an existing authentication for users which is already working fine. The token for user authentication expires within an hour.
I want to implement another separate authentication strategy a third API that is consuming my Nestjs API. There are separate endpoints for the third-party API, the token should expire with 24 hours. The API has to stay connected to my app for 24 hours.
I don't mind using additional package to achieve this.
I also need to create a guard called thirdParty Guard so that the 3rd part API alone will have access to that endpoint.
This is my jwt.strategy.ts
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.SECRETKEY
});
}
async validate(payload: any, done: VerifiedCallback) {
const user = await this.authService.validateUser(payload);
if (!user) {
return done(
new HttpException('Unauthorised access', HttpStatus.UNAUTHORIZED),
false,
);
}
//return user;
return done(null, user, payload.iat)
}
}
ApiKey.strategy.ts
@Injectable()
export class ApiKeyStrategy extends PassportStrategy(HeaderAPIKeyStrategy) {
constructor(private authService: AuthService) {
super({
header: 'api_key',
prefix: ''
}, true,
(apikey: string, done: any, req: any, next: () => void) => {
const checkKey = this.authService.validateApiKey(apikey);
if (!checkKey) {
return done(
new HttpException('Unauthorized access, verify the token is correct', HttpStatus.UNAUTHORIZED),
false,
);
}
return done(null, true, next);
});
}
}
and this is the auth.service.ts
@Injectable()
export class AuthService {
constructor(private userService: UserService) { }
async signPayLoad(payload: any) {
return sign(payload, process.env.SECRETKEY, { expiresIn: '1h' });
}
async validateUser(payload: any) {
const returnuser = await this.userService.findByPayLoad(payload);
return returnuser;
}
validateApiKey(apiKey: string) {
const keys = process.env.API_KEYS;
const apiKeys = keys.split(',');
return apiKeys.find(key => apiKey === key);
}
}
Upvotes: 12
Views: 6386
Reputation: 144
With the above setup, If you are using Passport-HeaderAPIKey
then try adding headerapikey
in the Guard. The below code worked for me.
import { ExecutionContext, Injectable } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { AuthGuard as NestAuthGuard } from '@nestjs/passport';
@Injectable()
export class AuthGuard extends NestAuthGuard(['jwt', 'headerapikey']) {
constructor(private readonly reflector: Reflector) {
super();
}
canActivate(context: ExecutionContext) {
const isPublic = this.reflector.getAllAndOverride<boolean>('isPublic', [
context.getHandler(),
context.getClass(),
]);
if (isPublic) {
return true;
}
return super.canActivate(context);
}
}
Upvotes: 4