繁体   English   中英

如何处理内部服务器错误? Nestjs

[英]How to handle the Internal server error? Nestjs

如何处理错误,以便如果用户不提供令牌,则抛出 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;
    }
  }

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

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

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

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

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 中间件文档
  2. 问题详情

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM