为何我的Nuxt代理在生产环境配置下无法正常工作?
我们使用@nuxtjs/proxy隐藏API端点,本地开发时请求正常,但部署到staging环境后,所有请求均返回401未授权错误。
相关配置
nuxt.config.js基础配置
const deployTarget = process.env.NUXTJS_DEPLOY_TARGET || 'server' const deploySSR = (process.env.NUXTJS_SSR === 'true') || (process.env.NUXTJS_SSR === true)
代理配置
proxy: { '/api/**/**': { changeOrigin: true, target: process.env.VUE_APP_API_URL, secure: true, ws: false, pathRewrite: { '^/api/': '' } } },
部署命令
NUXTJS_DEPLOY_TARGET=server NUXTJS_SSR=false nuxt build && NUXTJS_DEPLOY_TARGET=server NUXTJS_SSR=false nuxt start
HttpClient构造函数修改
原代码:
constructor (basePath, defaultTimeout, fetch, AbortController) { this.basePath = basePath this.defaultTimeout = parseInt(defaultTimeout, 10) || 1000 this.isLocalhost = !this.basePath || this.basePath.includes('localhost') this.fetch = fetch this.AbortController = AbortController }
修改后:
constructor (basePath, defaultTimeout, fetch, AbortController) { this.basePath = '/api' this.defaultTimeout = parseInt(defaultTimeout, 10) || 1000 this.isLocalhost = !this.basePath || this.basePath.includes('localhost') this.fetch = fetch this.AbortController = AbortController }
Fetch选项配置
_getOpts (method, options) { const opts = Object.assign({}, options) opts.method = opts.method || method opts.cache = opts.cache || 'no-cache' opts.redirect = opts.redirect || 'follow' opts.referrerPolicy = opts.referrerPolicy || 'no-referrer' opts.credentials = opts.credentials || 'same-origin' opts.headers = opts.headers || {} opts.headers['Content-Type'] = opts.headers['Content-Type'] || 'application/json' if (typeof (opts.timeout) === 'undefined') { opts.timeout = this.defaultTimeout } return opts }
错误响应
{ "code": 401, "data": "{'statusCode':401,'error':'Unauthorized','message':'Invalid token.'}", "json": { "statusCode": 401, "error": "Unauthorized", "message": "Invalid token." }, "_isJSON": true }
备注
- 前端部署在需要基础HTTP认证的
example.com,已完成正确认证 - 本地和staging环境的请求均指向无需HTTP认证的
api.example.com,数据由无令牌要求的Strapi提供
核心问题
是否可能因为代理发起的请求未携带HTTP认证,导致出现该401响应?
回答
这确实是可能的,但实际逻辑是代理误携带了前端的基础认证头,被API判定为无效令牌,具体原因:
- 前端部署在需基础HTTP认证的域名下,用户访问时浏览器会自动在请求该域名资源时带上
Authorization: Basic <编码后的账号密码>头。 - Nuxt代理转发请求时,默认会将前端请求的所有请求头(包括这个
Authorization)转发给目标API。 - 目标Strapi API不需要认证,但它会尝试解析
Authorization头中的内容作为JWT令牌,而前端的基础认证字符串不符合JWT格式,因此返回"Invalid token"的401错误。
解决方案建议
方案1:在代理配置中清空Authorization头
proxy: { '/api/**/**': { changeOrigin: true, target: process.env.VUE_APP_API_URL, secure: true, ws: false, pathRewrite: { '^/api/': '' }, headers: { Authorization: '' // 强制清空该头 } } },
方案2:通过钩子移除请求头
proxy: { '/api/**/**': { changeOrigin: true, target: process.env.VUE_APP_API_URL, secure: true, ws: false, pathRewrite: { '^/api/': '' }, onProxyReq: (proxyReq) => { proxyReq.removeHeader('Authorization') // 转发前移除该头 } } },
补充说明
前端fetch配置中的credentials: 'same-origin'仅控制浏览器端的凭证携带逻辑,代理属于服务器端转发,不受该配置影响,无需修改。
内容的提问来源于stack exchange,提问作者Toni Michel Caubet
相关产品推荐
相关产品推荐

