Nestjs中如何实现多种passport jwt认证策略
How to implement multiple passport jwt authentication strategies in Nestjs
我现有的用户身份验证已经运行良好。用户身份验证令牌将在一小时内过期。
我想实施另一个单独的身份验证策略,第三个 API 正在使用我的 Nestjs API。第三方 API 有单独的端点,令牌应在 24 小时后过期。 API 必须与我的应用保持连接 24 小时。
我不介意使用额外的包来实现这一点。
我还需要创建一个名为 thirdParty Guard 的守卫,以便第三部分 API 单独访问该端点。
这是我的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);
});
}
}
这是 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);
}
}
通过上述设置,如果您使用的是 Passport-HeaderAPIKey
然后尝试在 Guard 中添加 headerapikey
。下面的代码对我有用。
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);
}
}
我现有的用户身份验证已经运行良好。用户身份验证令牌将在一小时内过期。
我想实施另一个单独的身份验证策略,第三个 API 正在使用我的 Nestjs API。第三方 API 有单独的端点,令牌应在 24 小时后过期。 API 必须与我的应用保持连接 24 小时。
我不介意使用额外的包来实现这一点。
我还需要创建一个名为 thirdParty Guard 的守卫,以便第三部分 API 单独访问该端点。
这是我的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);
});
}
}
这是 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);
}
}
通过上述设置,如果您使用的是 Passport-HeaderAPIKey
然后尝试在 Guard 中添加 headerapikey
。下面的代码对我有用。
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);
}
}