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

问题描述

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

如果有令牌,则解码信息,如果没有令牌,则希望得到未定义的信息。

始终必须有 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) {
		...
	}
})

标签: node.jsjwtgraphqlpassport.jsnestjs

解决方案


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

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);
}

推荐阅读