node.js - Cách triển khai nhiều chiến lược xác thực passport jwt trong Nestjs
Tôi có một hệ thống xác thực cho người dùng hiện tại đang hoạt động tốt. Token để xác thực người dùng hết hạn trong vòng một giờ.
Tôi muốn triển khai một chiến lược xác thực riêng biệt khác cho một API thứ ba đang sử dụng API Nestjs của tôi. Có các điểm cuối riêng biệt cho API của bên thứ ba, token sẽ hết hạn sau 24 giờ. API phải duy trì kết nối với ứng dụng của tôi trong 24 giờ.
Tôi không ngại sử dụng gói bổ sung để đạt được điều này.
Tôi cũng cần tạo một guard gọi là thirdParty Guard để API bên thứ ba sẽ có quyền truy cập duy nhất vào endpoint đó.
Đây là jwt.strategy.ts của tôi
@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);
});
}
}
và đây là 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);
}
}
Câu trả lời #1
Với cài đặt trên, nếu bạn đang sử dụng Passport-HeaderAPIKey thì hãy thử thêm headerapikey vào Guard. Đoạn mã dưới đây đã hoạt động với tôi.
Tham chiếu: NestJS mở rộng guard
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);
}
}
