React配置setupProxy代理后如何阻止外部直接访问/api接口
阻止外部用户直接访问/api接口的解决方案
问题原因
你当前的CORS配置只能阻止跨域脚本发起的请求,无法限制同域下直接发起的请求(比如用户直接在地址栏输入https://example.com/api/todos、用Postman等工具发起请求),这些请求会正常经过React的代理转发到Node服务,所以可以正常拿到返回结果。
推荐解决方案
方案1:接口增加鉴权校验(最安全,推荐)
从业务层对接口做身份校验,无论请求来自哪里,都需要携带合法的鉴权凭证才能访问:
- 给需要保护的接口加登录态校验,比如要求请求头携带合法的JWT Token,或者Cookie中携带合法的Session标识,未通过校验的请求直接返回401状态码。
示例代码(Node端):
// 自定义鉴权中间件 const authMiddleware = (req, res, next) => { // 从请求头取Authorization字段的Token,也可以从Cookie取Session const token = req.headers.authorization?.split(' ')[1] // 自定义校验逻辑:比如验证Token签名、有效期、是否对应有效用户 if (!token || !validateToken(token)) { return res.status(401).json({ error: '未授权访问' }) } next() } // 给需要保护的接口绑定鉴权中间件 app.get('/api/todos', authMiddleware, (req, res) => { // 原有业务逻辑 })
方案2:代理层加自定义请求头校验(临时可用)
如果是非敏感接口、暂时不想加鉴权逻辑,可以通过代理和Node服务配合做私有请求头校验,过滤不是从React代理转发的请求:
- 修改
setupProxy配置,转发请求时附加一个只有你知道的自定义私有头:
const createProxyMiddleware = require(`http-proxy-middleware`) module.exports = function (app) { app.use('/api/*', createProxyMiddleware({ target:'http://localhost:4000', changeOrigin: true, // 新增自定义私有头,值替换为你自己生成的随机字符串 headers: { 'X-Proxy-Secret': '自定义的随机字符串,比如a3f2d9s8x7c6v' } })) }
- Node端新增全局中间件,校验所有/api路径的请求是否携带正确的私有头:
app.use('/api/*', (req, res, next) => { if (req.headers['x-proxy-secret'] !== '自定义的随机字符串,比如a3f2d9s8x7c6v') { return res.status(403).json({ error: '禁止访问' }) } next() })
注意:该方案只能防普通用户直接发起的请求,无法防御抓包拿到私有头后模拟的请求,安全性低于方案1。
方案3:限制Node服务仅本地可访问(从网络层阻断)
因为你的Node服务只需要被本地的React代理访问,不需要对外暴露端口,可以直接把Node服务的监听地址绑定为本地回环地址127.0.0.1,外部网络无法直接访问4000端口:
// 将原有监听逻辑修改为绑定127.0.0.1 app.listen(4000, '127.0.0.1', () => { console.log('服务仅本地可访问,地址:http://127.0.0.1:4000') })
额外提示:你当前配置的origin为
http://localhost:3000的CORS规则已经失效,对外暴露的域为https://example.com且所有/api请求走代理转发不会触发跨域校验,可删除多余的CORS配置。
内容的提问来源于stack exchange,提问作者Sasi C
相关产品推荐
相关产品推荐

