第7篇:RESTful API设计与安全防护
在前后端分离架构中,RESTful API是系统交互的核心通道。本文将从接口规范设计到安全防护,全面讲解如何在EggJS中构建安全、规范、易用的API系统,并提供完整的解决方案和最佳实践。
一、标准化API接口规范设计
1. RESTful设计原则
核心要素:
- 资源导向:`/users` 而不是 `/getUsers`
- HTTP方法语义化:GET(查询) | POST(创建) PUT(全量更新) | PATCH(部分更新)DELETE(删除)
- 版本控制:`/api/v1/users`
- 状态码标准化:200 OK | 201 Created | 400 Bad Request
- 过滤分页:`/users?page=2&size=10&sort=-created_at`
2. 接口设计规范
URI设计示例:
// 用户资源
GET /api/v1/users // 获取用户列表
POST /api/v1/users // 创建新用户
GET /api/v1/users/{id} // 获取指定用户
PUT /api/v1/users/{id} // 全量更新用户
DELETE /api/v1/users/{id} // 删除用户// 子资源操作
GET /api/v1/users/{id}/orders // 获取用户订单
设计要点:
- 使用复数名词表示资源集合
- 避免在URI中使用动词
- 嵌套资源不超过两级
- 查询参数统一驼峰命名
二、统一响应格式与错误处理
1. 响应格式标准化
通用响应结构(app/middleware/response_formatter.js
):
module.exports = () => {return async (ctx, next) => {try {await next();if (ctx.body && !ctx.body.code) {ctx.body = {code: 200,data: ctx.body,message: 'success'};}} catch (err) {ctx.status = err.status || 500;ctx.body = {code: err.code || ctx.status,message: err.message,data: null};}};
};
2. 错误处理机制
自定义错误类型(app/errors/index.js
):
class BusinessError extends Error {constructor(code, message) {super(message);this.code = code;this.status = 400;}
}class UnauthorizedError extends Error {constructor(message = '未授权访问') {super(message);this.code = 401;this.status = 401;}
}module.exports = { BusinessError, UnauthorizedError };
控制器使用示例:
async login() {const { ctx } = this;const user = await ctx.service.user.find(ctx.request.body);if (!user) {throw new ctx.app.errors.UnauthorizedError('账号或密码错误');}// ...登录逻辑
}
三、安全防护实战方案
1. JWT认证实现
JWT配置(config/config.default.js
):
module.exports = {jwt: {secret: process.env.JWT_SECRET || 'default_key',expiresIn: '2h' // 令牌有效期}
};
认证中间件(app/middleware/jwt_auth.js
):
const { JWT } = require('jsonwebtoken');module.exports = options => {return async (ctx, next) => {const token = ctx.get('Authorization').replace('Bearer ', '');try {const decoded = JWT.verify(token, ctx.app.config.jwt.secret);ctx.state.user = decoded;await next();} catch (err) {ctx.throw(401, '无效的访问令牌');}};
};
2. CSRF防御配置
安全配置(config/config.default.js
):
module.exports = {security: {csrf: {enable: true,type: 'all', // 防御所有非安全方法ignoreJSON: false,cookieName: 'csrfToken',sessionName: 'csrfToken',headerName: 'x-csrf-token'}}
};
前端配合方案:
// 从cookie获取csrfToken
const csrfToken = document.cookie.match(/csrfToken=([^;]+)/)[1];// 请求头携带token
fetch('/api/data', {method: 'POST',headers: {'x-csrf-token': csrfToken}
});
四、API文档生成与Swagger集成
1. Swagger配置
安装插件:
npm install egg-swagger-doc --save
配置插件(config/plugin.js
):
exports.swaggerdoc = {enable: true,package: 'egg-swagger-doc'
};
文档配置(config/config.default.js
):
module.exports = {swaggerdoc: {dirScanner: './app/controller',apiInfo: {title: 'XXX平台API',description: 'XXX平台 RESTful API 文档',version: '1.0.0'},schemes: ['http', 'https'],consumes: ['application/json'],produces: ['application/json'],securityDefinitions: {JWT: {type: 'apiKey',name: 'Authorization',in: 'header'}}}
};
2. 接口注释规范
控制器注释示例:(app/controller/user.js
)
/*** @Controller UserRouter --用户相关接口*/
class UserCtr extends Controller {// 业务代码
}/*** @router post /api/v1/login* @summary 用户登录* @description 通过账号密码获取访问令牌* @request body loginRequest* @response 200 loginResponse 登录成功* @response 401 errorResponse 认证失败*/
async login() {// 登录逻辑
}
模型定义示例:
app/contract/request/user.js
module.exports = {loginRequest: {id: {type: 'string', required: true, example: 'admin', remark: '用户编码'},password: {type: 'string', required: true, example: '****', remark: '用户密码'}}
}app/contract/response/user.js
module.exports = {loginResponse: {code: {type: 'integer', required: true, example: 'admin', remark: '响应码'},message: {type: 'string', required: true, example: 'success', remark: '请求响应消息'}}
}
五、最佳实践建议
-
安全增强措施:
- 敏感接口启用HTTPS
- 关键操作添加二次验证
- 接口访问频率限制
-
版本管理策略:
- URI版本:/api/v1/resource - Header版本:Accept: application/vnd.myapi.v1+json - 旧版本维护周期不超过6个月
-
文档维护规范:
- 接口变更同步更新文档
- 生产环境禁用文档页面
- 使用Postman维护接口用例
总结
规范的API设计与安全防护是构建可靠Web系统的基石,通过本文可以掌握:
- 符合行业标准的接口设计方法
- 统一的异常处理机制
- JWT+CSRF双重安全保障
- 自动化文档生成方案
这些实践方案已在多个大型项目中验证,能够显著提升API系统的可维护性和安全性。欢迎在评论区留下你遇见的「RESTful API」设计经验与挑战,共同探讨最佳实践!