我是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"
};
}
}
答案 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
中。