在开发后台管理系统时,我们经常需要为演示环境添加操作限制,防止访客随意修改数据。本文将介绍如何在 NestJS 中实现类似若依框架的演示环境守卫。
核心实现
1、创建演示环境守卫
demo-environment.guard.ts
// src\common\guard\demo-environment.guard.ts
import { ConfigService } from '@nestjs/config'
import { BusinessException } from '../exception/business.exception'
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common'
/**
* 演示环境操作守卫
* @description 用于限制演示环境的操作权限:
* 1. 非演示环境:直接放行所有请求
* 2. 演示环境:仅允许 GET 请求 + 白名单内的非GET请求,其他请求直接抛出异常
*/
@Injectable()
export class DemoEnvironmentGuard implements CanActivate {
constructor(private readonly configService: ConfigService) {}
/**
* 守卫核心方法:判断请求是否允许执行
* @param context 执行上下文(可获取请求/响应信息)
* @returns 允许返回true,拒绝则抛出业务异常
*/
async canActivate(context: ExecutionContext): Promise<boolean> {
// 1. 从配置中获取是否为演示环境,默认值:非演示环境
const isDemoEnvironment = this.configService.get('server.isDemo', false)
// 2. 非演示环境 → 直接放行所有请求
if (!isDemoEnvironment) return true
// 3. 演示环境 → 获取 HTTP 请求对象
const request = context.switchToHttp().getRequest<ExpressRequest>()
const requestMethod = request.method.toUpperCase()
// 4. 演示环境放行白名单(支持登录/登出等基础接口)
const whiteList = ['/login', '/logout']
// 5. 判断当前请求路径是否在白名单中
const isWhite = whiteList.some((item) => request.originalUrl.includes(item))
// 6. 演示环境拦截规则:非 GET 请求 + 不在白名单 → 拒绝访问
if (requestMethod !== 'GET' && !isWhite) throw new BusinessException('演示环境,不允许操作')
// 7. 符合规则 → 放行
return true
}
}
2. 全局注册守卫
// src\app.module.ts
import { APP_GUARD } from '@nestjs/core'
import { DemoEnvironmentGuard } from '@/common'
@Module({
providers: [
// 是否演示环境守卫
{ provide: APP_GUARD, useClass: DemoEnvironmentGuard },
]
})
3. 配置文件示例
# config\config.yaml
server:
isDemo: true # 开启演示模式
工作原理
- 环境判断:通过
configService读取配置,判断当前是否为演示环境 - 请求拦截:演示环境下,所有非 GET 请求(除白名单外)都会被拦截
- 友好提示:拦截时抛出业务异常,前端可捕获并提示用户
使用效果
- 开发/生产环境:所有请求正常放行,不受限制
- 演示环境:
- ✅ GET 请求正常访问
- ✅
/login、/logout等白名单接口正常访问 - ❌ 其他 POST/PUT/DELETE 请求被拦截,返回「演示环境,不允许操作」
总结
通过实现 CanActivate 接口,我们仅用 30 行代码就完成了演示环境守卫的开发。这种实现方式简洁高效,完美复刻了若依框架的演示模式功能,非常适合在开源项目或在线体验系统中使用。