Node.js Express 如何限制API路由仅响应自家前端与移动端请求
适配Express栈的无预令牌API来源拦截实现方案
针对你api/v1/track路由需要在用户登录前即可被自家前端、App调用,同时屏蔽外部无关访问的需求,不需要依赖JWT预校验,按三层防护逻辑实现即可:
1. 基于CORS白名单的前端来源校验
这是挡外部跨域调用的基础层,依赖浏览器原生的跨域校验机制:只有你在白名单内的Vue SPA域名发起的跨域请求,浏览器才会允许读取接口返回值,外部站点就算把接口地址抄走,跨域请求也会被浏览器拦截拿不到数据。
实现逻辑就是在路由前置中间件里校验请求携带的Origin请求头,匹配白名单即可放行:
// 白名单存储允许访问的前端域名 const ALLOWED_FRONTEND_ORIGINS = new Set([ "https://你的线上VueSPA域名", "http://localhost:8080" // 本地开发调试域名 ]) // 挂载到track路由的前置校验中间件 app.use("/api/v1/track", (req, res, next) => { // 移动端App发起的请求不会携带Origin头,这类请求直接跳到App专属校验逻辑 if (!req.headers.origin) return next() // Origin不在白名单内的请求直接拒绝 if (!ALLOWED_FRONTEND_ORIGINS.has(req.headers.origin)) { return res.status(403).json({ msg: "无权访问接口" }) } next() })
2. 针对移动端App的专属请求标识校验
移动端App发起的请求没有浏览器自带的Origin头,不能直接放开无Origin的请求,否则会被外部爬虫直接遍历调用。你可以在自己App的全局网络请求封装里,给所有发往服务端的请求加一个固定的、只有你的App代码才知道的自定义请求头,服务端校验这个头的值匹配就放行:
// 接着上面的track路由中间件逻辑,处理无Origin的App请求 const APP_CLIENT_HEADER_NAME = "x-internal-app-tag" // 这个值随机生成,写在你App的网络请求封装里,不要对外公开 const VALID_APP_TAG = "track-app-9f2k3d7x2" // 无Origin的请求,必须携带匹配的App标识才放行 if (!req.headers[APP_CLIENT_HEADER_NAME] || req.headers[APP_CLIENT_HEADER_NAME] !== VALID_APP_TAG) { return res.status(403).json({ msg: "无权访问接口" }) } next()
注意:不要靠User-Agent判断是否为App请求,这个值很容易被伪造;也不要把这个标识当成高安全级别的密钥,它的作用只是挡掉无针对性的批量爬虫。
3. 轻量限流做兜底防护
就算前面两层校验过了,也需要加一层IP维度的轻量限流,避免被人拿到标识后批量爬取数据。不需要依赖用户令牌,直接用基于IP维度的限流规则即可:
const rateLimit = require("express-rate-limit") // 配置规则:同一个IP1分钟内最多请求20次track接口 const trackInterfaceLimiter = rateLimit({ windowMs: 60 * 1000, max: 20, standardHeaders: true, legacyHeaders: false }) // 把限流规则挂到track路由上 app.use("/api/v1/track", trackInterfaceLimiter)
补全原有路由逻辑
经过上面三层中间件校验后,进入路由处理逻辑的请求都是你允许的来源,直接返回对应数据即可:
app.get("/api/v1/track/:ID" , (req , res) => { const trackId = req.params.ID // 原有业务逻辑:根据trackId查询对应数据 const trackData = getTrackDataById(trackId) res.json(trackData) })
方案说明:这套逻辑完全不需要提前给用户生成JWT令牌,既满足了你需要在用户登录前就给Vue SPA同步数据的需求,又能挡住绝大多数外部无关调用,不需要做复杂的预授权流程。
内容的提问来源于stack exchange,提问作者Momo
相关产品推荐
相关产品推荐

