如何在没有守卫装饰器的情况下始终验证 JWT? (Nest.js + 护照)

Posted

技术标签:

【中文标题】如何在没有守卫装饰器的情况下始终验证 JWT? (Nest.js + 护照)【英文标题】:How to always validate JWT without guards decorator? (Nest.js + passport) 【发布时间】:2020-02-23 18:43:19 【问题描述】:

我在项目中使用了nest.js + passport + jwt + graphql。

如果有令牌,则解码信息, 如果没有令牌,想得到 undefined。

始终必须有 Guards 才能接收解码的令牌。

我可以选择性地生成 401 错误吗?

@Module(
  providers: [
    JwtStrategy,
  ],
  imports: [
    PassportModule.register( defaultStrategy: 'jwt' ),
    JwtModule.register(
      secret: 'hi',
      signOptions:  expiresIn: '1d' ,
    ),
  ],
)
export class AuthModule 



export class GqlAuthGuard extends AuthGuard('jwt') 
  getRequest(context: ExcutionContext) 
    const ctx = GqlExecutionContext.create(context)
    return ctx.getContext().req
  



export class JwtStrategy extends PassportStrategy(Strategy) 
  constructor() 
    super(
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      ignoreExpiration: false,
      secretOrKey: config.jwt.secret,
    )
  
  
  validate(payload: JwtPayload): any 
    return  user_id: +payload.user_id , username: payload.username 
  


@Resolver(() => Test)
export class TestResolver 
  @UseGuards(GqlAuthGuard) // I want to get validated users without guards.
  @Query(() => Test)
  startTest(
    @User() user: any, // req.user
  ) 
    console.log(user)
  

我不知道这是否可能,但我想要这个代码。

app.use((req, res, next) => 
	if (req.headers.token)  // optional
		try 
			req.user = verify(req.headers.token)
		 catch (err) 
			req.user = undefined
		
	

	next()
)

app.get((req, res, next) => 
	if (req.user) 
		...
	
)

【问题讨论】:

如果没有要解码的令牌,得到 undefined 的目的是什么?这不是意味着它是未经身份验证的用户,您应该返回 401 吗? @JayMcDoniel 如果标头中有标记,我想使用该用户的信息进行搜索。但是,必须有一个Guard才能进行验证,如果没有token,则输出401。Guard很难使用,因为它必须有一个token。 我的意思是,在守卫中你可以说if (!token) return false,然后nest 可以处理剩下的事情 向文本添加内容。这份文件说,req 必须从 Guard 退回。 docs.nestjs.com/techniques/authentication#graphql不知道是不是我记错了…… 在你添加的快递代码sn -p中,如果没有token,你想做什么?现在看起来你只是去next(),并不关心是否给出了令牌 【参考方案1】:

你可以像这样应用全局警卫

async function bootstrap(): Promise<void> 
    const app = await NestFactory.create(AppModule);

    const reflector = app.get(Reflector);
    app.useGlobalGuards(new GqlAuthGuard(reflector));

    await app.listen(process.env.PORT);

【讨论】:

感谢您的回答!我需要不需要身份验证的查询和需要的查询。在一个 Query 中验证令牌,但不想产生 401 错误。 您可以通过实现@Public 装饰器为您的查询设置元数据来绕过全局防护,在我的博客trejgun.github.io 中有几个示例

以上是关于如何在没有守卫装饰器的情况下始终验证 JWT? (Nest.js + 护照)的主要内容,如果未能解决你的问题,请参考以下文章

在没有 IIS 管理器的情况下禁用基本身份验证

如何在没有身份验证的情况下创建 JWT 令牌

如何在没有密钥或没有验证的情况下解码 php/laravel 中的 jwt?

如何在没有 Microsoft 身份的情况下对 blazor 服务器进行 jwt 身份验证?

如何在没有 x5c 的情况下从 jwks 验证 JWT 的签名

Flask 学习-32.flask_jwt_extended 自定义装饰器