对不起,我的英语不好,我来自乌克兰:) 您能否告诉我如何创建我自己的服务,该服务是npm包中jwt模块提供的Jwt服务的扩展?我想为捕获错误创建自己的JwtService,并隔离重复的逻辑以进行令牌创建和验证。请帮我怎么做。随附代码示例。
import { BadRequestException, Injectable } from '@nestjs/common';
import { JwtService as NestJwtService, JwtVerifyOptions } from '@nestjs/jwt';
@Injectable()
export class OwnJwtService extends NestJwtService {
constructor() {
super({});
}
async verifyAsync<T>(token: string, options?: JwtVerifyOptions): Promise<T> {
try {
const res = await super.verifyAsync(token, options);
console.log('res', res);
return res;
} catch (error) {
// My own logic here ...
throw new BadRequestException({
error,
message: 'Error with verify provided token',
});
}
}
}
或者也许我需要将nestjs jwt服务注入到我自己的服务中?例如:
import { BadRequestException, Injectable } from '@nestjs/common';
import { JwtService as NestJwtService, JwtVerifyOptions } from '@nestjs/jwt';
@Injectable()
export class OwnJwtService {
constructor(private readonly jwtService: NestJwtService) {}
async verifyAsync<T>(token: string, options?: JwtVerifyOptions): Promise<T> {
try {
const res = await this.jwtService.verifyAsync(token, options);
console.log('res', res);
return res;
} catch (error) {
throw new BadRequestException({
error,
message: 'Error with verify provided token',
});
}
}
}
和
import { JwtModule as NestJwtModule } from '@nestjs/jwt';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { OwnJwtService } from 'src/modules/jwt/jwt.service';
@Module({
imports: [
NestJwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
signOptions: {
expiresIn: process.env.JWT_EXPIRES_IN,
},
secret: process.env.JWT_SECRET,
secretOrPrivateKey: process.env.JWT_SECRET,
}),
inject: [ConfigService],
}),
],
providers: [OwnJwtService],
exports: [OwnJwtService],
})
export class JwtModule {}
但这对我不起作用,并且我有类似的错误:
错误:Nest无法解析OwnJwtService(?)的依赖项。请确保在AuthModule上下文中索引[0]处的参数JwtService可用。
答案 0 :(得分:0)
首先,请注意,JwtModule基本上是基于jsonwebtoken
创建一个模块的,您的自定义错误并非要在其中处理。
第二,当您使用 registerAsync 时,您应该使用configService.get('JWT_SECRET')
中的ConfigService获取ENV变量。
第三,您的问题效率低下。 JwtModule已经可以满足您的所有需求。您只需要实现它。同样,只要将其视为适用于Nest的jsonwebtoken
软件包即可。就是这样。
在注册时,登录和刷新令牌(如果存在)会在您创建新令牌时路由sign
。
在您的请求中间件中,您verify
。
Nest的一大问题是其文档。它没有您需要的一切。验证路由的方法可能不止一种,但最直接的方法就是使用Express中间件,就像在典型的Express应用中一样。
为此,您需要像这样在AppModule中实现它:
@Module(...)
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer): MiddlewareConsumer | void {
consumer.apply(cookieParser(), AuthMiddleware).forRoutes('/');
}
}
在此示例中,我还将注册模块cookieParser()
,因为我将令牌发送到cookie中。其他cookie模块也可以。 NestModule和MiddlewareConsumer都来自@ nestjs / common。
AuthMiddleware是我使用此框架制作的中间件...
export class AuthMiddleware implements NestMiddleware {
constructor(
private readonly configService: ConfigService,
private readonly jwtService: JwtService
) {}
async use(req: Request, res: Response, next: NextFunction) {
const { yourJwtToken } = req.cookies;
const isValidToken = this.jwtService.verify(
yourJwtToken,
this.configService.get('JWT_SECRET'),
);
if (!isValidToken) throw new UnauthorizedException();
// etc...
next();
}
}
最后,您可能要问的是应用AuthGuard。
如果您使用Passport,则只需遵循文档以应用它们。如果您,他们已经抛出了错误。如果要更改它,只需重写其方法即可。
您也可以手动执行。只需使用控制台生成防护,就可以在其中检查身份验证context.switchToHttp().getRequest()
并在检查凭据后返回布尔值,并根据需要使用构造函数检查权限。
如果愿意,您也可以从上方跳过中间件配置,并在防护装置内实现逻辑。
再次,我真的不认为更改JwtModule在这里是最好的主意。