微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

NestJS/GraphQL/Passport - 从警卫那里得到未经授权的错误

如何解决NestJS/GraphQL/Passport - 从警卫那里得到未经授权的错误

我正在尝试遵循此 tutorial 并且正在努力将实现转换为 GraphQL。

local.strategy.ts

@Injectable()
export class LocalStrategy extends PassportStrategy(Strategy) {
  constructor(private readonly authenticationService: AuthenticationService) {
    super();
  }

  async validate(email: string,password: string): Promise<any> {
    const user = await this.authenticationService.getAuthenticatedUser(
      email,password,);

    if (!user) throw new UnauthorizedException();

    return user;
  }
}

local.guard.ts

@Injectable()
export class LogInWithCredentialsGuard extends AuthGuard('local') {
  async canActivate(context: ExecutionContext): Promise<boolean> {
    const ctx = GqlExecutionContext.create(context);
    const { req } = ctx.getContext();
    req.body = ctx.getArgs();

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

authentication.type.ts

@InputType()
export class AuthenticationInput {
  @Field()
  email: string;

  @Field()
  password: string;
}

authentication.resolver.ts

@UseGuards(LogInWithCredentialsGuard)
@Mutation(() => User,{ nullable: true })
logIn(
  @Args('variables')
  _authenticationInput: AuthenticationInput,@Context() req: any,) {
  return req.user;
}

突变

mutation {
  logIn(variables: {
    email: "email@email.com",password: "123123"
  } ) {
    id
    email
  }
}

即使上述凭据是正确的,我也收到了未经授权的错误

解决方法

问题出在您的 LogInWithCredentialsGuard

您不应该覆盖 canAcitavte 方法,您所要做的就是使用适当的 graphql args 更新请求,因为在 API 请求的情况下,passport 会自动从 req.body 获取您的凭据,但如果是 graphql 执行上下文是不同的,因此您必须在 req.body 中手动设置参数,并为此使用 getRequest 方法。

由于 graphql 和 rest api 的执行上下文不同,你必须确保你的守卫在这两种情况下都有效,无论是控制器还是变异。

这是一个有效的代码片段

@Injectable()
export class LogInWithCredentialsGuard extends AuthGuard('local') {
  // Override this method so it can be used in graphql
  getRequest(context: ExecutionContext) {
    const ctx = GqlExecutionContext.create(context);
    const gqlReq = ctx.getContext().req;
    if (gqlReq) {
      const { variables } = ctx.getArgs();
      gqlReq.body = variables;
      return gqlReq;
    }
    return context.switchToHttp().getRequest();
  }
}

你的突变会像

@UseGuards(LogInWithCredentialsGuard)
@Mutation(() => User,{ nullable: true })
logIn(
  @Args('variables')
  _authenticationInput: AuthenticationInput,@Context() context: any,// <----------- it's not request
) {
  return context.req.user;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?