NestJS - 将用户数据从自定义身份验证防护传递到解析器



我知道这个问题经常被问到默认护照AuthGuard('yourStrategy'(, 但尚未找到自定义身份验证保护的答案。

为什么使用自定义身份验证防护?因为默认的和 GraphQL 似乎无法协同工作。 由于 GraphQL 端进行了一些更新,默认的 AuthGuard 无法再读取标头。

我需要以某种方式将从持有者令牌获得的用户数据传递给解析器。 护照是怎么做到的?你会怎么做?我对nestJS很陌生,缺乏dockumentation和/或propper教程让我发疯。

相关代码:

auth.guard.ts

@Injectable()
export class AuthGuard implements CanActivate {
constructor(readonly jwtService: JwtService/*, readonly userService: UsersService*/) { }
canActivate(context: ExecutionContext): boolean {
const ctx = GqlExecutionContext.create(context);
const request = ctx.getContext().request;
const Authorization = request.get('Authorization');
if (Authorization) {
const token = Authorization.replace('Bearer ', '');
const { userId, firstName } = this.jwtService.verify(token)  as { userId: string; firstName: string } ;
return !!userId;
}
}
}

JWT.strategy.ts

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private readonly authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: jwtConstants.secret,
});
}
async validate(payload) {
return {userId: payload.userId, firstName: payload.firstName};
}
}

auth.module.ts

@Module({
imports: [
forwardRef(() => UserModule) , 
PassportModule.register({
defaultStrategy: 'jwt'
}), 
JwtModule.register({
secret: jwtConstants.secret,
signOptions: {expiresIn: 3600}
})],
providers: [AuthService, JwtStrategy, AuthResolver, AuthGuard],
exports: [AuthService, JwtModule, AuthGuard]
})
export class AuthModule {
}

示例解析程序

@UseGuards(AuthGuard)
@Resolver((of) => UserSchema)
export class UserResolver {
constructor(private readonly userService: UserService) {}
// ===========================================================================
// Queries
// ===========================================================================
@Query(() => UserDto, {description: 'Searchs for a user by a given id'})
async getUserById(@Args('id') id: string) {
/*
* Instead of passing the userID as an query argument, get it from the bearer token / auth guard!
*/
const result = await this.userService.findById(id);
if(result) return result;
return new NotFoundException('User not found!');
}
}

提前感谢您的帮助! ;-(

编辑:如果您需要查看更多代码,您可以使用我的github存储库:https://github.com/JensUweB/ExamAdmin-Backend

没关系。我自己找到了解决这个问题的方法。我找到了一种解决方法,可以让护照AuthGuard恢复与GraphQL一起使用。对于用户ID:使用自定义用户装饰器:github.com/nestjs/graphql/issues/48#issuecomment-420693225

最新更新