当我将另一个服务注入 nestjs 中的用户服务时如何修复未知的身份验证策略 "jwt"

How to fix unknown authentication strategy "jwt" when I inject another service into user service in nestjs

我有一个处理注册、登录和其他一些功能的用户服务。我已经使用 10 多个模块开发应用程序一段时间了。但是我注意到,每次我注入另一个服务并尝试使用任何端点时,我都会收到此错误 "Unknown authentication strategy "jwt". 招摇错误是:-

Internal Server Error
Response body

{
  "statusCode": 500,
  "message": "Internal server error"
}

一旦我从用户模块中删除了注入的服务,一切又都好了。我一直在尝试解决这个问题,因为我需要在用户模块中使用这个服务。

这是jwt.Strategy.ts

import { Injectable, HttpException, HttpStatus } from "@nestjs/common";
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt, VerifiedCallback } from "passport-jwt";
import { AuthService } from './auth.service';

@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);
        try {
            if (user) {
                //return user;
                return done(null, user, payload.iat)
            } else if (user == null) {
                const Terminal = await this.authService.validatePos(payload);
                return done(null, Terminal, payload.iat)
            }
            else {
                return done(
                    //throw new UnauthorizedException();
                    new HttpException('Unauthorised access', HttpStatus.UNAUTHORIZED),
                    false,
                );
            }

        } catch (error) {
            return error;
        }
    }
}

这是 AuthModule

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { UserService } from '../user/user.service';
import { UserSchema } from '../user/user.schema';
import { MongooseModule } from '@nestjs/mongoose';
import { JwtStrategy } from './jwt.strategy';
import { ActivityLogService } from '../activity-log/activity-log.service';
import { ApiKeyStrategy } from './apiKey.strategy';
import { PassportModule } from "@nestjs/passport";

@Module({
    imports: [MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
    PassportModule.register({
        secret: "mysec"
    }),
        ActivityLogService],
    providers: [AuthService, UserService, JwtStrategy, ApiKeyStrategy, ActivityLogService],
    exports: [AuthService],
    controllers: []
})
export class AuthModule { }

这是api.strategy.ts

import { HeaderAPIKeyStrategy } from 'passport-headerapikey';
import { PassportStrategy } from '@nestjs/passport';
import { Injectable, HttpException, HttpStatus } from '@nestjs/common';
import { AuthService } from './auth.service';

@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);
            });
    }
}

这是authService


import { Injectable } from '@nestjs/common';
import { sign } from 'jsonwebtoken';
import { UserService } from '../user/user.service';
import { TerminalService } from '../terminal/terminal.service';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { Terminal } from '../terminal/interfaces/terminal.interface';


@Injectable()
export class AuthService {
    constructor(private userService: UserService, @InjectModel('Terminal') private terminalModel: Model<Terminal>,) { }

    //generate token for user
    async signPayLoad(payload: any) {
        return sign(payload, process.env.SECRETKEY, { expiresIn: '1h' });
    }

    //find user with payload
    async validateUser(payload: any) {
        const returnuser = await this.userService.findByPayLoad(payload);
        return returnuser;
    }

    //generate token for Posy
    async signPosPayLoad(payload: any) {
        return sign(payload, process.env.SECRETKEY, { expiresIn: '24h' });
    }

    //find terminal with payload
    async validatePos(payload: any) {
        const { terminalId } = payload;
        const terminal = await this.terminalModel.findById(terminalId);
        return terminal;
    }

    validateApiKey(apiKey: string) {
        const keys = process.env.API_KEYS;
        const apiKeys = keys.split(',');
        return apiKeys.find(key => apiKey === key);
    }
}


这是用户服务

import { Injectable, HttpException, HttpStatus, Inject } from '@nestjs/common';
import { User } from './interfaces/user.interface';
import { Model } from 'mongoose';
import { InjectModel } from '@nestjs/mongoose';
import { LoginUserDto } from './login-user.dto';
import { ActivityLogService } from '../activity-log/activity-log.service';
import { UpdateUserDTO } from './dtos/update_user.dto';

@Injectable()
export class UserService {
    constructor(@InjectModel('User') private userModel: Model<User>,
        private activityLogService: ActivityLogService,
    ) { }
    
    //Login user
    private users = [
        {
            "userId": 1,
            "name": "John Doe",
            "username": "john",
            "password": "john123"
        },
    ]
    async login(loginDTO: LoginUserDto) {

        const { email, password } = loginDTO;

        return await this.users.find(users => users.username == email)
    }

    async findByPayLoad(payload: any) {
        const { userId } = payload;
        return await this.userModel.findById(userId)
    }
    async getAllUser() {
        return this.users;
    }
}

我不知道我做错了什么

除了代码难以操纵和确定发生了什么,服务在他们不应该的地方以及服务在各处的重新实例化之外,导致错误的罪魁祸首仅仅是因为你永远不要从 @nestjs/passport

注册 PassportModule

编辑 2017 年 1 月 7 日

大约一年半后回到这个答案,看起来真正的问题是在策略中使用 REQUEST 作用域提供程序。 The nest docs explicitly mention this can't be done directly but also have a workaround for it.