【问题标题】:How to handle the Internal server error? Nestjs如何处理内部服务器错误?巢穴
【发布时间】:2021-10-22 20:18:11
【问题描述】:

如何处理错误,如果用户不提供令牌,则抛出 UnauthorizedException。

目前我收到此错误:

{
    "statusCode": 500,
    "message": "Internal server error"
}

ts:

  canActivate(context: ExecutionContext) {
    const request = context.switchToHttp().getRequest();
    try {
      const jwt = request.headers.authorization.split(' ')[1];

      if (!jwt) {
        throw new UnauthorizedException('Token is not provided.');
      }

      return this.jwtService.verify(jwt);
    } catch (e) {
      return false;
    }
  }

【问题讨论】:

  • request.headers.authorization undefined?这个内部服务器错误是从哪里来的??

标签: javascript node.js nestjs


【解决方案1】:

您可以尝试从文档中重新创建身份验证模块。 或者尝试在每一行上 console.log()。

默认情况下,JWT 内部模块运行良好。它可以自动编码和解码您需要的所有内容。

https://docs.nestjs.com/security/authentication

【讨论】:

    【解决方案2】:

    我为此使用了一个中间件。我将分享它的基本版本。

    auth-middleware.ts

    import {HttpStatus,Injectable,Logger,LoggerService,NestMiddleware,} from '@nestjs/common';
    import { NextFunction } from 'express';
    import { Request, Response } from 'express';
    
    @Injectable()
    export class AuthMiddleware implements NestMiddleware {
      constructor(
        private readonly authenticationService: AuthService, 
    // (I use Firebase auth. You can inject JWT service here instead)
        private readonly logger: LoggerService, // Good'ol logger
      ) {}
      public async use(req: Request, res: Response, next: NextFunction) {
        // Checks if req has authorization header
        const header = req.headers['authorization'];
        if (!header) {
        // If no headers are present, returns a 401.
        // I use problem+json
        // Thats why you are seeing more fields in the response instead of just a 
        // code and message
          return res
            .status(HttpStatus.UNAUTHORIZED)
            .json({
              title: 'Unauthorized',
              detail: 'Invalid Token',
              type: 'https://app-site.com/login',
              status: HttpStatus.UNAUTHORIZED,
              instance: 'login/null',
            })
            .setHeader('Content-Type', 'application/problem+json');
        }
        // Splitting "Bearer token" to ["Bearer","token"]
        const token = header.split(' ')[1];
       // Validating token with auth service
       // It returns a "tuple" for me...you can have it return whatever you want
        const [
          authClaims, // Custom claims that is extracted from the JWT
          result, // JWT Validation result (boolean)
          authProviderUid, // Firebase UID
        ] = await this.authenticationService.verifyToken(token);
        if (
          !result || // If JWT is invalid
          authClaims.accountStatus === AccountStatusList.Banned ||
          authClaims.accountStatus === AccountStatusList.Suspended
        ) {
          // You shall not pass
          return res
            .status(HttpStatus.UNAUTHORIZED)
            .json({
              title: 'Unauthorized',
              detail: 'Invalid Token',
              type: 'https://app-site.com/login',
              status: HttpStatus.UNAUTHORIZED,
              instance: 'login/null',
            })
            .setHeader('Content-Type', 'application/problem+json');
        }
        // Attaches the claims, result and UID with req for the next middleware(s)/controller
        req['authResult'] = { authClaims, result, authProviderUid };
        //Reassuring 
        this.logger.log('Token verified', AuthMiddleware.name);
       // next function from express
        next();
      }
    }
    

    接下来,在模块中声明您的控制器,

    api.module.ts

    import { MiddlewareConsumer, Module, NestModule, RequestMethod, } from '@nestjs/common';
    
    @Module({
      imports: [
        //...
      ],
      controllers: [
        AuthController,
        ProfileController,
        SubscriptionController
      ],
      providers: [
        //...
      ],
    })
    export class ApiModule implements NestModule {
      public async configure(consumer: MiddlewareConsumer) {
        consumer
          .apply(AuthMiddleware)
          // Exclude some paths
          .exclude({ path: '/api/v1/auth/sign-up', method: RequestMethod.POST })
          .forRoutes( // Your controller classes you want to run the middleware on
            ProfileController,
            SubscriptionController,
            AuthController
          );
      }
    }
    
    

    它是如何工作的

    每个请求都通过指定的中间件(如果不排除路径)。如果请求未经授权,则在到达控制器之前引发错误。

    如果请求在控制器处,则请求已通过身份验证。您必须与警卫等一起处理授权部分...

    身份验证和授权是不同的。

    我建议使用中间件进行身份验证并使用保护来进行授权。

    链接:

    1. NestJS Middleware Documentation
    2. Problem Details

    【讨论】:

      猜你喜欢
      • 2020-06-10
      • 2022-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-08
      • 1970-01-01
      相关资源
      最近更新 更多