后端如何验证收到的请求来自合法前端而非第三方恶意请求?
入门教程省略校验配置的原因
绝大多数入门级开发教程的核心目标是让开发者快速跑通全栈流程,所以会刻意省略生产环境所需的安全校验步骤,你提到的未配置前端访问白名单就是这类情况,你参考的MERN栈记忆帖项目作为教学演示项目,初期版本也没有全量开启所有安全规则。
多层级校验实现方案
实际生产环境会通过多层校验组合的方式解决恶意请求问题,具体实现逻辑如下:
第一层:浏览器跨域规则(CORS)防护
后端可以通过CORS配置限定仅允许指定域名的前端请求访问接口,比如你前端部署在Netlify、后端在Heroku的场景,只需要在Express后端安装cors依赖后添加如下配置:const cors = require('cors'); app.use(cors({ origin: 'https://你绑定的Netlify域名.com', // 仅允许该域名的跨域请求 credentials: true }));配置完成后,所有来自其他域名的前端跨域请求会被浏览器直接拦截,无法到达后端。注意该规则仅对浏览器环境生效,无法拦截Postman、后端脚本等非浏览器场景的直接请求,需要配合下一层校验。
第二层:用户身份与权限校验(核心防护)
这一层是防止数据被恶意篡改删除的核心逻辑,你参考的记忆帖项目中已经包含了完整实现,可以查看项目中/server/middleware/auth.js文件:- 用户登录成功后,后端会生成加密的JWT令牌返回给前端,前端后续所有增删改请求都需要在请求头中携带该令牌
- 后端收到请求后,会优先校验JWT的合法性,不合法的请求直接返回401未授权错误
- 处理具体操作前,后端会二次校验当前登录用户是否具备对应资源的操作权限:比如删除记忆帖时,会校验该帖的创建者ID是否和当前登录用户ID一致,不一致直接返回403无权限错误
核心校验代码示例:
// auth.js 中间件逻辑 const token = req.headers.authorization.split(" ")[1]; const decodedData = jwt.verify(token, process.env.JWT_SECRET_KEY); req.userId = decodedData.id; // 删除接口逻辑 const post = await PostMessage.findById(req.params.id); if(post.creator !== req.userId) return res.status(403).json({message: "无权操作该资源"});这套规则下,哪怕有人恶意构造请求发送到后端,没有合法的登录令牌或者没有对应资源的操作权限,也无法修改或删除数据库内容。
第三层:传输层安全防护
强制使用HTTPS部署前后端服务,目前Netlify、Heroku都默认提供免费HTTPS证书,加密后的通信内容即使被第三方监听,也无法窃取请求中的JWT令牌或者篡改请求内容。
常见疑问补充
你担心的“第三方自行编写前端调用接口”的问题并不会造成数据风险:第三方编写的前端要么因为CORS规则被浏览器拦截,要么没有合法的用户登录令牌,哪怕拿到了普通用户的令牌,也只能操作该用户自己的资源,不会影响全量数据库数据。
内容的提问来源于stack exchange,提问作者anrasd43

