javascript - 如何处理内部服务器错误?巢穴
问题描述
如何处理错误,以便如果用户不提供令牌,则会引发 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-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
);
}
}
这个怎么运作
每个请求都通过指定的中间件(如果不排除路径)。如果请求未经授权,则在到达控制器之前引发错误。
如果请求在控制器处,则请求被验证。您必须与警卫等一起处理授权部分......
身份验证和授权是不同的。
我建议使用中间件进行身份验证并使用保护进行授权。
链接:
推荐阅读
- apache - 在 Linux (Centos) 的 httpd 中没有重新指定每个子线程的默认值?
- python - 管道预处理步骤将模型得分值转换为 NaN
- sql - 用于简单 SQL 查询的 JPA Query
- r - 使用 RSelenium 的不完整页面数据
- python - 关于 Django 的问题。协助实施赛事报名
- google-sheets - 在 Google 工作表中拆分后获取单元格的 vlookup
- mongodb - 如何使用 sbt 为 scala 版本 3 安装 mongo-scala-driver?
- mysql - 如何使用 python 变量形成 SQL CREATE TABLE 语句
- java - Java Google 搜索程序不会打印搜索结果
- python - 如何在pyhive中使用'with'子句?