Nest无法解析JwtStrategy的依赖项

时间:2020-08-01 16:00:49

标签: nestjs typeorm

我是NestJs世界的新手。据我所知,我导入了JwtStrategy中所需的所有内容。我不知道哪里出了问题。有人可以帮我吗?

就我提到的文档化而言,每当我们要在模块中使用任何实体时,都应在@Module()装饰器的imports字段中导入该实体。我做到了。

jwt.strategy.ts

import { Injectable, UnauthorizedException } from "@nestjs/common";
import { PassportStrategy } from "@nestjs/passport";
import { Strategy, ExtractJwt } from "passport-jwt";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { UserEntity } from "src/entities/user.entity";
import { AuthPayload } from "src/common/dtos/user.dto";

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
    constructor(
        @InjectRepository(UserEntity)
        private userRepo: Repository<UserEntity>
    ) {
        super({
            jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
            secretOrKey: process.env.SECRETKEY
        });
    }

    async validate(payload: AuthPayload): Promise<UserEntity> {
        const { username } = payload;
        const user = this.userRepo.findOne({ where: { username: username } });
        if(!user) {
            throw new UnauthorizedException();
        }
        return user;
    }
}

auth.module.ts

import { Module } from '@nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UserEntity } from 'src/entities/user.entity';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { JwtStrategy } from './jwt.strategy';

@Module({
  imports: [
    TypeOrmModule.forFeature([UserEntity]),
    JwtModule.register({
      secret: process.env.SECRETKEY,
    }),
    PassportModule.register({
      defaultStrategy: 'jwt'
    })
  ],
  providers: [AuthService, JwtStrategy],
  controllers: [AuthController],
  exports: [PassportModule, JwtStrategy]
})
export class AuthModule {}

user.entity.ts

import { Entity, Column, OneToMany, JoinTable, BeforeInsert } from "typeorm";
import { AbstractEntity } from "./abstract-entity.abstract";
import { IsEmail } from "class-validator";
import { Exclude, classToPlain } from "class-transformer";
import * as bcrypt from "bcryptjs";
import { CategoryEntity } from "./category.entity";
import { ArticleEntity } from "./article.entity";

@Entity('User')
export class UserEntity extends AbstractEntity {
    @Column({
        type: "varchar",
        length: 80
    })
    fullName: string;

    @Column({
        type: "varchar",
        unique: true
    })
    @IsEmail()
    email: string;

    @Column({
        type: "varchar",
        unique: true
    })
    username: string;

    @Column({
        type: "varchar"
    })
    @Exclude()
    password: string;

    @Column({
        default: null,
        nullable: true
    })
    avatar: string | null;

    @Column({
        type: "varchar",
        unique: true
    })
    phoneNumber: string;

    @Column({
        type: "boolean",
        default: false
    })
    isAdmin: boolean;

    @Column({
        type: "boolean",
        default: false
    })
    isStaff: boolean;

    @Column({
        type: "boolean",
        default: false
    })
    isEmailVerified: boolean;

    @OneToMany(type => CategoryEntity, category => category.createdBy)
    @JoinTable()
    categories: CategoryEntity[];

    @OneToMany(type => ArticleEntity, article => article.createdBy)
    @JoinTable()
    articles: ArticleEntity[];

    @BeforeInsert()
    async hashPassword() {
        this.password = await bcrypt.hash(this.password, 10);
    }

    async comparePassword(attempt: string): Promise<boolean> {
        return await bcrypt.compare(attempt, this.password);
    }

    toJSON(): any {
        return classToPlain(this);
    }
}

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from "@nestjs/typeorm";
import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core';
import { 
  DatabaseConnectionService
 } from "./utils/database-connection.service";
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
import { ArticlesModule } from './articles/articles.module';
import { HttpExceptionFilter } from './common/exception-filters/http-exception.filter';
import { ResponseInterceptor } from './common/interceptors/response.interceptor';
import { CategoryModule } from './category/category.module';

@Module({
  imports: [
    TypeOrmModule.forRootAsync({
      useClass: DatabaseConnectionService
    }),
    AuthModule,
    UsersModule,
    ArticlesModule,
    CategoryModule,
  ],
  controllers: [AppController],
  providers: [
    // {
    //   provide: APP_INTERCEPTOR,
    //   useClass: ResponseInterceptor
    // },
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter
    },
    AppService
  ],
})
export class AppModule {}

database-connection.service.ts

import { Injectable } from "@nestjs/common";
import { TypeOrmOptionsFactory, TypeOrmModuleOptions } from "@nestjs/typeorm";
import { truncate } from "fs";

@Injectable()
export class DatabaseConnectionService implements TypeOrmOptionsFactory {
    createTypeOrmOptions(): TypeOrmModuleOptions {
        return {
            type: "mysql",
            host: process.env.HOST,
            port: parseInt(process.env.PORT),
            username: process.env.DB_USERNAME,
            password: process.env.DB_PASSWORD,
            database: process.env.DATABASE, 
            entities: [__dirname + '/**/*.entity{.ts,.js}'],
            synchronize: true,
            dropSchema: true,
            autoLoadEntities: true,
            logger: "simple-console"
        };
    }
}

错误如下: enter image description here

2 个答案:

答案 0 :(得分:2)

考虑移动到活动记录模式。您要做的就是让您的AbstractEntity扩展TypeOrm的BaseEntity

您可以删除所有导入的typeorm功能,例如:

TypeOrmModule.forFeature([UserEntity])

以及存储库的所有依赖项注入,例如:

@InjectRepository(UserEntity)
private userRepo: Repository<UserEntity>

只需使用实体类进行查询:

const user = await UserEntity.findOne({ where: { username: username } });

答案 1 :(得分:2)

根据您的错误,您在JwtStrategy数组中有imports的某个地方。如果您需要JwtStrategy,则应该导入AuthModule,因为提供程序只能位于providers数组中,而永远不能位于imports中。