身份验证章节和19-auth示例的问题

问题描述 投票:1回答:2

我下载了19-auth示例并向其添加了一些console.log调试代码,然后发现了一些问题。

JwtAuthGuard中的代码永远不会执行:'2222222'未在下面的代码中打印到控制台:

canActivate(context: ExecutionContext) {
console.log('22222222222');
// add your custom authentication logic here
// for example, call super.logIn(request) to establish a session.
return super.canActivate(context);
}

当我在AuthController中将防护改为JwtAuthGuard时:

@get('data')
@UseGuards(JwtAuthGuard)
findAll(@Req() req) {
return req.user;
// this route is restricted by AuthGuard
// JWT strategy
}

调用了JwtAuthGuard中的代码,但在canActivate函数中,我无法从请求中获取用户信息。并且在JwtStrategy之前调用了canActivate函数?

有人可以解释auth模块的代码执行方式,以及如何在JwtAuth Guard中获取用户信息吗?

在此处粘贴最新代码和控制台日志:

JwtStrategy

/**
   * jwt passport 调用validate方法来判断是否授权用户进行接口调用
   * @param payload
   */
  async validate(payload: AuthPayload) {
    Logger.log(`payload is ${JSON.stringify(payload)}`, 'JwtStrategy');
    const user = await this.authService.validateUser(payload.id);
    if (!user) {
      throw new UnauthorizedException('不存在的用户信息');
    }
    return user;
  }

JwtAuthGuard

canActivate(context: ExecutionContext) {
    // add your custom authentication logic here
    // for example, call super.logIn(request) to establish a session.
    // this.accessPriv = this.reflector.get<string>('accessPriv', context.getHandler());
    console.log('canActivate executed 111111111111111111');
    return super.canActivate(context);
  }

和控制台日志如下:

canActivate executed 111111111111111111

[Nest] 14080   - 2019-04-01 11:19   [JwtStrategy] payload is {"userName":"fanliang","id":"1","iat":1553772641,"exp":1554377441} +2286ms
it seems that the canActivate() function of JwtAuthGuard executed before the validate() function of JwtStrategy, but the user info was attached to the request after JwtStrategy validate().

我想要的是在自定义AuthGuard的canActivate()中获取请求中的用户信息,例如JwtAuthGuard

nestjs
2个回答
0
投票

我有一个适合我的解决方案。在我自己的逻辑之前调用super.canActivate。 似乎是由它触发的req.user的人口。 一个例子:

import { ExecutionContext, Injectable } from "@nestjs/common";
import { AuthGuard } from "@nestjs/passport";
import { Request } from "express";

@Injectable()
export class AuthGuardWithAllowSentry extends AuthGuard("jwt") {
  public async canActivate(context: ExecutionContext) {
    // that code will call the passport jwt
    const origCanActivate = await super.canActivate(context);
    // now we have request.user!


    const http = context.switchToHttp();
    const request = http.getRequest<Request>();

    console.log(request.user)

    if (request.header("X-Sentry-Token") === "blablabla") {
      if (request.method === "GET" && request.path.endsWith(".map")) {
        return true;
      }
    }

    // some random logic
    return request.user.roles.includes("admin")
  }
}

对我来说,感觉更像是一种解决方法,而不是一种真实的东西。


-1
投票

我同意19-auth样本有点令人困惑。这主要是因为它包括JWTAuthGuard(作为建立自定义守卫的参考)但它从未实际使用过。相反,原始使用普通AuthGuard已经设置为提供JWT功能。然而,两名警卫都利用了JWTStrategy。如果你想更好地理解这一点,你可以尝试更新你的AuthController

  @Get('data')
  @UseGuards(AuthGuard())
  findAll() {
    // this route is restricted by AuthGuard
    // JWT strategy
    return {
      message: 'Successfully passed AuthGuard',
    };
  }

  @Get('custom-jwt')
  @UseGuards(new JwtAuthGuard())
  // this route is restricted by JWTAuthGuard custom
  // JWT strategy
  customJwt() {
    return {
      message: 'Successfully passed JWTAuthGuard',
    };
  }

重要的是,为了通过任何一个保护,您必须发送请求,并将Authorization标头正确设置为从token端点返回的标记。

例如:Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAZW1haWwuY29tIiwiaWF0IjoxNTU0MDUyNDczLCJleHAiOjE1NTQwNTYwNzN9.3Q8_FC-qFXk1F4KmMrHVSmmNGPAyHdt2myr5c18_E-U

我发现最简单的方法是使用像Postman或Insomnia这样的工具来构建请求和设置Headers等,但你也可以使用CURL。一旦您使用有效令牌设置Authorization标头,您就可以击中两个受保护的端点。如果你在JWTStrategy中放置一个console.log,你会看到两个警卫最终都使用validate方法来正确地检索用户。

© www.soinside.com 2019 - 2024. All rights reserved.