如何在Nestjs中实现多个passport jwt认证策略

tec*_*ack 8 authentication node.js typescript passport.js nestjs

我有一个已经可以正常工作的用户身份验证。用户认证的令牌在一小时内过期。

我想实现另一个单独的身份验证策略,即使用我的 Nestjs API 的第三个 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)
    }
}
Run Code Online (Sandbox Code Playgroud)

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);
            });
    }
}
Run Code Online (Sandbox Code Playgroud)

这是 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 4

通过上述设置,如果您正在使用,Passport-HeaderAPIKey请尝试添加headerapikeyGuard。下面的代码对我有用。

参考:NestJS 扩展防护

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);
  }
}
Run Code Online (Sandbox Code Playgroud)