Я знаю, что этот вопрос часто задают для паспорта по умолчанию AuthGuard ('yourStrategy'), но я еще не нашел ответа для пользовательских средств проверки подлинности.
Почему я использую пользовательские средства проверки подлинности? Потому что по умолчанию и GraphQL, похоже, не могут работать вместе. Так как некоторое обновление на стороне GraphQL, AuthGuard по умолчанию больше не может читать заголовок.
Мне нужно каким-то образом передать пользовательские данные, которые я получил от токена-носителя, резолверам. Как паспорт делает это? Как бы вы это сделали? Я плохо знаком с гнездом JS, и отсутствие руководств по документированию и / или проппорту сводит меня с ума.
Соответствующий код:
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