基于用户角色,通过Redoc单文件OpenAPI实现文档权限管控
基于用户角色过滤Redoc Standalone展示的API内容
不用维护多份API文档,通过以下步骤就能实现单份文档根据用户角色动态展示内容:
1. 给OpenAPI文档添加角色权限元数据
在OpenAPI的每个接口操作里,自定义扩展字段(比如x-allowed-roles),标注允许访问该接口的角色。示例:
openapi: 3.0.3 info: title: 示例API version: 1.0.0 paths: /admin/users: get: x-allowed-roles: ["admin"] summary: 管理员查看用户列表 responses: '200': description: 成功返回用户列表 /user/profile: get: x-allowed-roles: ["user", "admin"] summary: 用户查看个人资料 responses: '200': description: 成功返回个人资料 /public/health: get: summary: 公开健康检查接口(无角色限制) responses: '200': description: 服务正常
注:没有添加x-allowed-roles的接口默认对所有角色可见,你也可以根据需求改成默认隐藏。
2. 从PHP后端传递当前用户角色
在渲染Redoc的页面中,通过PHP把当前登录用户的角色输出到前端全局变量:
<script> // 从SESSION或后端接口获取当前用户角色 const currentUserRole = "<?php echo htmlspecialchars($_SESSION['user_role'] ?? 'guest'); ?>"; </script>
3. 过滤OpenAPI Spec后再渲染Redoc
Redoc Standalone支持动态传入处理后的Spec,所以我们可以先加载原始Spec,根据当前角色过滤后再初始化Redoc:
<!-- 引入Redoc Standalone脚本 --> <script src="https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"></script> <!-- Redoc渲染容器 --> <div id="redoc-container"></div> <script> // 加载原始OpenAPI Spec(这里假设后端返回JSON格式,若为YAML需用js-yaml解析) fetch('/path/to/your/openapi.json') .then(res => res.json()) .then(rawSpec => { // 复制原始Spec,避免修改原数据 const filteredSpec = { ...rawSpec }; filteredSpec.paths = {}; // 遍历所有路径和接口操作 Object.entries(rawSpec.paths).forEach(([path, pathOperations]) => { const allowedOperations = {}; Object.entries(pathOperations).forEach(([method, operation]) => { const allowedRoles = operation['x-allowed-roles'] || []; // 判断当前角色是否有权限查看该接口 if (allowedRoles.length === 0 || allowedRoles.includes(currentUserRole)) { allowedOperations[method] = operation; } }); // 如果该路径下还有允许的接口,保留到过滤后的Spec中 if (Object.keys(allowedOperations).length > 0) { filteredSpec.paths[path] = allowedOperations; } }); // 用过滤后的Spec初始化Redoc Redoc.init(filteredSpec, {}, document.getElementById('redoc-container')); }); </script>
关键注意事项
- 前端仅做展示过滤:后端必须在接口层面做权限校验,不能依赖前端隐藏接口来保障安全,否则用户可以直接通过HTTP请求调用未被展示的接口。
- Spec格式兼容:如果你的OpenAPI是YAML格式,需要引入
js-yaml库将其解析为JSON后再处理。 - 角色逻辑扩展:可以根据需求调整过滤规则,比如支持角色继承(如
admin自动拥有user的权限),或者默认隐藏无权限标识的接口。
内容的提问来源于stack exchange,提问作者Alfred
相关产品推荐
相关产品推荐

