NestJS – Passport JWT策略未将用户附加到请求对象。

huangapple go评论71阅读模式
英文:

NestJS - Passport JWT strategy does not attach user to request object

问题

I am building an auth flow using NextAuth on a Next.js frontend, and Passport JWT on a NestJS + GraphQL backend. NextAuth gets a JWT token from a third party provider, and then attaches it to the auth header. In the backend, it is handled by a global auth guard.

Here is the guard:

@Injectable()
export class GqlAuthGuard extends AuthGuard('jwt') {
  constructor(@Inject(UserRoleMetadataService) private readonly userRoleMetadataService: UserRoleMetadataService) {
    super();
  }

  canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
    if (this.userRoleMetadataService.isPublicResource(context)) {
      return true;
    }

    return super.canActivate(context);
  }

  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return this.userRoleMetadataService.getRequestWithAuthHeaders(ctx);
  }
}

Validate method from strategy:

async validate(req, payload: KnomeJwtPayload): Promise<UserEntity> {
    const user = await this.userService.getOrCreateUser(payload);

    await this.verifyAuthorization(req, user.roles);
    const isOwnerRequired = this.userRoleMetadataService.readIsOwnerRequiredHeader(req);
    if (isOwnerRequired) {
      this.verifyOwnership(req, user.id);
    }

    return user;
  }

and user decorator:

const CurrentUser = createParamDecorator((data, ctx) => {
  const context = GqlExecutionContext.create(ctx).getContext();
  return context.req.user;
})

Everything is working as expected up until the return statement from the strategy. I logged the user object that is returned, and it is exactly what I expect. However, for some reason that user object is not being attached to the request and is therefore undefined in the decorator. What am I doing wrong?

英文:

I am building an auth flow using NextAuth on a Next.js frontend, and Passport JWT on a NestJS + GraphQL backend. NextAuth gets a JWT token from a third party provider, and then attaches it to the auth header. In the backend, it is handled by a global auth guard.

Here is the guard:

@Injectable()
export class GqlAuthGuard extends AuthGuard(&#39;jwt&#39;) {
  constructor(@Inject(UserRoleMetadataService) private readonly userRoleMetadataService: UserRoleMetadataService) {
    super();
  }

  canActivate(context: ExecutionContext): boolean | Promise&lt;boolean&gt; | Observable&lt;boolean&gt; {
    if (this.userRoleMetadataService.isPublicResource(context)) {
      return true;
    }

    return super.canActivate(context);
  }

  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    return this.userRoleMetadataService.getRequestWithAuthHeaders(ctx);
  }
}

Validate method from strategy:

async validate(req, payload: KnomeJwtPayload): Promise&lt;UserEntity&gt; {
    const user = await this.userService.getOrCreateUser(payload);

    await this.verifyAuthorization(req, user.roles);
    const isOwnerRequired = this.userRoleMetadataService.readIsOwnerRequiredHeader(req);
    if (isOwnerRequired) {
      this.verifyOwnership(req, user.id);
    }

    return user;
  }

and user decorator:

const CurrentUser = createParamDecorator((data, ctx) =&gt; {
  const context = GqlExecutionContext.create(ctx).getContext();
  return context.req.user;
})

Everything is working as expected up until the return statement from the strategy. I logged the user object that is returned, and it is exactly what I expect. However, for some reason that user object is not being attached to the request and is therefore undefined in the decorator. What am I doing wrong?

答案1

得分: 1

The object returned by the getRequest method needs to be the same instance as ctx.req so that when you access ctx.req it has the new properties. As you mentioned in a comment it was a shallow copy but has been reworked to be the same object reference.

英文:

The object returned by the getRequest method needs to be the same instance as ctx.req so that when you access ctx.req it has the new properties. As you mentioned in a comment it was a shallow copy but has been reworked to be the same object reference

huangapple
  • 本文由 发表于 2023年6月29日 18:43:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/76580279.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定