【问题标题】:Nestjs + Passport: Prevent user 1 to access information of user 2Nestjs + Passport:防止用户1访问用户2的信息
【发布时间】:2021-09-22 13:05:13
【问题描述】:

如何防止用户 1 在 Nesjs 应用中使用护照访问用户 2 的信息?

我已经有 2 个策略:

  • 使用电子邮件/密码验证用户的本地策略。受此策略保护的路由返回一个 jwt 令牌。

  • 验证给定 jwt 令牌的 jwt 策略。

现在,我想将users/:id 等路由的访问权限限制为实际上具有相同 userId 加密的 jwt 令牌。

怎么做?

【问题讨论】:

    标签: node.js authentication passport.js nestjs nestjs-passport


    【解决方案1】:

    编辑

    我混合了 AuthenticationAuthorization:一旦用户通过身份验证,我想要实现的就是授权。

    我不得不使用 Guard:

    own.guard.ts

    @Injectable()
    export class OwnGuard implements CanActivate {
      canActivate(context: ExecutionContext): boolean {
        const req = context.switchToHttp().getRequest();
        return req.user.id === req.params.id;
      }
    }
    

    然后在我的路由中使用它:

    @Get(':id')
    @UseGuards(OwnGuard)
    async get(@Param('id') id: string) {
      return await this.usersService.get(id);
    }
    

    原始答案

    我所做的是基于 jwt 创建第三种策略:

    @Injectable()
    export class OwnStrategy extends PassportStrategy(Strategy, 'own') {
      constructor() {
        super({
          jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
          secretOrKey: SECRET,
          passReqToCallback: true
        });
      }
    
      async validate(req: Request, payload: { sub: string }) {
        if (req.params.id !== payload.sub) {
          throw new UnauthorizedException();
        }
        return { userId: payload.sub };
      }
    }
    

    请注意我如何将自定义名称“own”作为PassportStrategy 的第二个参数传递,以将其与“jwt”区别开来。它的守卫:

    @Injectable()
    export class OwnAuthGuard extends AuthGuard('own') {}
    

    这可行,但我想知道这是否是好方法...

    如果以后我想为管理员用户修改用户怎么办?

    我应该创建一个检查role === Role.ADMIN || req.params.id === payload.sub 的第四个策略吗?

    我想我错过了一些东西。应该有一种方法可以创建一种策略,它只验证 jwt,另一个只验证 userId,另一个只验证角色,并在将警卫应用于我的路线时根据需要组合它们。

    【讨论】:

      【解决方案2】:

      同样的情况。你可以在guard中使用handleRequest方法。

      在这里您可以访问用户 auth 和 req,然后对适当的资源进行验证。查看我的代码

      @Injectable()
      export class JwtAuthGuard extends AuthGuard('jwt') {
          canActivate(context: ExecutionContext) {
              return super.canActivate(context);
          }
      
          handleRequest(err, user, info, context: ExecutionContext) {
              const request = context.switchToHttp().getRequest<Request>();
              const params = request.params;
              if (user.id !== +params.id) {
                  throw new ForbiddenException();
              }
      
              return user;
          }
      }
      

      在这里查看更多https://docs.nestjs.com/security/authentication#extending-guards

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-18
        • 1970-01-01
        • 2021-10-12
        • 2019-06-06
        • 1970-01-01
        • 1970-01-01
        • 2013-12-04
        相关资源
        最近更新 更多