我正在尝试用NestJ实现JWT。在我的user.module.ts
中,我添加了以下配置:
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { UserService } from './user.service';
import { UserResolver } from './user.resolver';
import { User } from './entities/user.entity';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AuthHelper } from './auth/auth.helper';
import { JwtStrategy } from './auth/auth.strategy';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
@Module({
imports: [
// PassportModule.register({ defaultStrategy: 'jwt', property: 'user' }),
// JwtModule.registerAsync({
// inject: [ConfigService],
// useFactory: (config: ConfigService) => ({
// secret: 'secret',
// signOptions: { expiresIn: 36000000 },
// }),
// }),
TypeOrmModule.forFeature([User]),
],
providers: [UserResolver, UserService], // AuthHelper, JwtStrategy],
})
export class UserModule {}
每当我取消评论这些行时,我就会遇到一些问题。
以下是一些相关的文件:
auth.strategy.ts
import { Injectable, Inject } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { User } from '../entities/user.entity';
import { AuthHelper } from './auth.helper';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
@Inject(AuthHelper)
private readonly helper: AuthHelper;
constructor(@Inject(ConfigService) config: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'KhubSecret',
ignoreExpiration: true,
});
}
private validate(payload: string): Promise<User | never> {
return this.helper.validateUser(payload);
}
}
auth.guard.ts
import { Injectable, ExecutionContext } from '@nestjs/common';
import { AuthGuard, IAuthGuard } from '@nestjs/passport';
import { User } from '../entities/user.entity';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') implements IAuthGuard {
public handleRequest(err: unknown, user: User): any {
return user;
}
public async canActivate(context: ExecutionContext): Promise<boolean> {
await super.canActivate(context);
const { user } = context.switchToHttp().getRequest();
return user ? true : false;
}
}
auth.helper.ts
import {
Injectable,
HttpException,
HttpStatus,
UnauthorizedException,
} from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import * as bcrypt from 'bcryptjs';
import { User } from '../entities/user.entity';
@Injectable()
export class AuthHelper {
@InjectRepository(User)
private readonly repository: Repository<User>;
private readonly jwt: JwtService;
constructor(jwt: JwtService) {
this.jwt = jwt;
}
public async decode(token: string): Promise<unknown> {
return this.jwt.decode(token, null);
}
public async validateUser(decoded: any): Promise<User> {
return this.repository.findOne(decoded.id);
}
public generateToken(user: User): string {
return this.jwt.sign({
id: user.userId,
username: user.username,
});
}
public isPasswordValid(password: string, userPassword: string): boolean {
return bcrypt.compareSync(password, userPassword);
}
public encodePassword(password: string): string {
const salt: string = bcrypt.genSaltSync(10);
return bcrypt.hashSync(password, salt);
}
private async validate(token: string): Promise<boolean | never> {
const decoded: unknown = this.jwt.verify(token);
if (!decoded) {
throw new HttpException('Forbidden', HttpStatus.FORBIDDEN);
}
const user: User = await this.validateUser(decoded);
if (!user) {
throw new UnauthorizedException();
}
return true;
}
}
我遇到了这样的错误:
[Nest] 18360 - 05/10/2022, 18:14:42 ERROR [ExceptionHandler] Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument ConfigService at index [0] is available in the JwtModule context.
Potential solutions:
- If ConfigService is a provider, is it part of the current JwtModule?
- If ConfigService is exported from a separate @Module, is that module imported within JwtModule?
@Module({
imports: [ /* the Module containing ConfigService */ ]
})
Error: Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument ConfigService at index [0] is available in the JwtModule context.
Potential solutions:
- If ConfigService is a provider, is it part of the current JwtModule?
- If ConfigService is exported from a separate @Module, is that module imported within JwtModule?
@Module({
imports: [ /* the Module containing ConfigService */ ]
})
我已经测试并实施了以下解决方案:
发布于 2022-11-11 07:33:51
这是解决办法。希望能帮上忙。
在您的auth策略中添加以下内容:
constructor() {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'KhubSecret',
ignoreExpiration: true,
});
}
而不是:
constructor(@Inject(ConfigService) config: ConfigService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: 'KhubSecret',
ignoreExpiration: true,
});
}
简单地说,删除
@Inject(ConfigService) config: ConfigService
来自构造函数的
发布于 2022-10-05 15:38:35
从您提供的即时错误来看,我将假设您的ConfigModule
不是全局的。这意味着您需要在ConfigModule
调用(在imports
数组中)中导入imports
。另一种选择是将ConfigModule
设置为全局(@nestjs/config
有此选项),以便您已经可以访问ConfigService
。
https://stackoverflow.com/questions/73960226
复制相似问题