NestJS 获取使用 JWT 身份验证的 GraphQL 解析器中的当前用户 [英] NestJS Get current user in GraphQL resolver authenticated with JWT

查看:30
本文介绍了NestJS 获取使用 JWT 身份验证的 GraphQL 解析器中的当前用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在将带有 Passport.js 的 JWT 身份验证实施到 NestJS 应用程序中.

I am currently implementing JWT authentication with Passport.js into a NestJS application.

在我的一些 GraphQL 解析器中,我需要访问当前经过身份验证的用户.我知道护照会将经过身份验证的用户附加到请求对象(至少我希望这是正确的),但我不知道如何在解析器中访问请求对象.

In some of my GraphQL resolvers I need to access the currently authenticated user. I know that passport will attach the authenticated user to the request object (at least I hope that this is correct), but I do not know how to access the request object inside a resolver.

我关注了这个问题 https://github.com/nestjs/nest/issues/1326 和提到的链接 https://github.com/ForetagInc/fullstack-boilerplate/tree/master/apps/api/src/app/auth 里面的问题.我在 GraphQL 解析器方法中看到了一些使用 @Res() res: Request 作为方法参数的代码,但我总是得到 undefined for res.

I followed the issue https://github.com/nestjs/nest/issues/1326 and the mentioned link https://github.com/ForetagInc/fullstack-boilerplate/tree/master/apps/api/src/app/auth inside the issue. I saw some code that uses @Res() res: Request as a method parameter in the GraphQL resolver methods, but I always get undefined for res.

这些是我目前的实现:

GQLAuth

import { Injectable, ExecutionContext } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { GqlExecutionContext } from '@nestjs/graphql';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
import { AuthenticationError } from 'apollo-server-core';

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  canActivate(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    const { req } = ctx.getContext();
    console.log(req);

    return super.canActivate(new ExecutionContextHost([req]));
  }

  handleRequest(err: any, user: any) {
    if (err || !user) {
      throw err || new AuthenticationError('GqlAuthGuard');
    }
    return user;
  }
}

需要访问当前用户的解析器

import { UseGuards, Req } from '@nestjs/common';
import { Resolver, Query, Args, Mutation, Context } from '@nestjs/graphql';
import { Request } from 'express';

import { UserService } from './user.service';
import { User } from './models/user.entity';
import { GqlAuthGuard } from '../auth/guards/gql-auth.guard';

@Resolver(of => User)
export class UserResolver {
  constructor(private userService: UserService) {}

  @Query(returns => User)
  @UseGuards(GqlAuthGuard)
  whoami(@Req() req: Request) {
    console.log(req);
    return this.userService.findByUsername('aw');
  }
}

JWT 策略

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';
import { AuthService } from './auth.service';
import { JwtPayload } from './interfaces/jwt-payload.interface';

@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authService: AuthService) {
    super({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: process.env.SECRET,
    });
  }

  async validate(payload: JwtPayload) {
    const user = await this.authService.validateUser(payload);
    if (!user) {
      throw new UnauthorizedException();
    }
    return user;
  }
}

授权和创建 JWT 令牌工作正常.GraphQL 守卫也适用于不需要访问用户的方法.但是对于需要访问当前经过身份验证的用户的方法,我看不出有什么办法.

Authorization and creating JWT tokens works fine. GraphQL guard also works fine for methods that do not need to access the user. But for methods that need access to the currently authenticated user, I see no way of getting it.

有没有办法完成这样的事情?

Is there a way to accomplish something like this ?

推荐答案

终于找到答案了... https://github.com/nestjs/graphql/issues/48#issuecomment-420693225 为我指明了创建用户装饰器

Finally found the answer ... https://github.com/nestjs/graphql/issues/48#issuecomment-420693225 pointed me into the right direction of creating a user decorator

// user.decorator.ts
import { createParamDecorator } from '@nestjs/common';

export const CurrentUser = createParamDecorator(
  (data, req) => req.user,
);

然后在我的解析器方法中使用它:

And then use this in my resolver method:

 import { User as CurrentUser } from './user.decorator';

 @Query(returns => User)
  @UseGuards(GqlAuthGuard)
  whoami(@CurrentUser() user: User) {
    console.log(user);
    return this.userService.findByUsername(user.username);
  }

现在一切都按预期进行.所以这个答案的所有功劳都归于 https://github.com/cschroeter

Now everything works as expected. So all credits of this answer goes to https://github.com/cschroeter

这篇关于NestJS 获取使用 JWT 身份验证的 GraphQL 解析器中的当前用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆