如何配置Nuxt与Axios以适配基于django-rest-framework和django-tenants的多租户子域名API
嘿,刚好我之前做过类似的Nuxt + Django多租户项目,给你梳理一套能直接落地的解决方案,针对你提到的两个核心问题逐一解决:
因为咱们的API是基于子域名区分租户的,不能用固定的baseURL,得根据当前访问的子域名动态生成。这里要兼顾开发/生产环境,还要考虑Nuxt的服务端渲染(SSR)场景。
1. 基础配置(nuxt.config.js)
先在配置文件里把Axios的baseURL留空,同时开启开发环境的代理:
export default { modules: [ '@nuxtjs/axios', '@nuxtjs/auth-next' ], axios: { baseURL: '', // 不设置固定值,后续动态配置 proxy: process.env.NODE_ENV === 'development' // 开发环境启用代理 }, // 开发环境代理配置:把子域名请求转发到Django服务 proxy: { '^/api': { target: 'http://localhost:8000', changeOrigin: true, onProxyReq: (proxyReq, req) => { // 把请求的host从Nuxt端口(3000)替换成Django端口(8000) const originalHost = req.headers.host.replace(':3000', ':8000') proxyReq.setHeader('Host', originalHost) } } } }
2. 动态设置BaseURL(Axios插件)
新建plugins/axios.js,用来在每次请求前根据当前环境(服务端/客户端)动态生成正确的API地址:
export default function ({ $axios, req, isServer }) { let apiBaseURL if (isServer) { // SSR场景下,从请求头获取当前子域名 const host = req.headers.host apiBaseURL = process.env.NODE_ENV === 'development' ? `http://${host.replace(':3000', ':8000')}/api` : `https://${host}/api` } else { // 客户端场景下,直接取当前窗口的host apiBaseURL = process.env.NODE_ENV === 'development' ? `http://${window.location.host.replace(':3000', ':8000')}/api` : `https://${window.location.host}/api` } $axios.defaults.baseURL = apiBaseURL // 加个请求拦截器兜底,确保所有请求都用正确的baseURL $axios.onRequest(config => { if (!config.baseURL) config.baseURL = apiBaseURL return config }) }
别忘了在nuxt.config.js的plugins数组里注册这个插件:
plugins: ['~/plugins/axios.js']
@nuxtjs/auth-next的认证端点可以和Axios的动态baseURL联动,这里推荐用动态配置的方案,确保认证请求自动适配当前租户子域名:
1. 基础Auth配置(nuxt.config.js)
先把认证策略的端点设为相对路径,后续动态拼接完整域名:
auth: { strategies: { local: { token: { property: 'access', global: true, type: 'Bearer' }, refreshToken: { property: 'refresh', maxAge: 60 * 60 * 24 * 30 }, // 先用相对路径,后续动态替换成完整地址 endpoints: { login: { url: '/login', method: 'post' }, logout: { url: '/logout', method: 'post' }, user: { url: '/user', method: 'get' } } } } }
2. 动态更新认证端点(Auth插件)
新建plugins/auth.js,和Axios插件逻辑一致,动态生成带租户子域名的认证地址:
export default function ({ $auth, req, isServer }) { let apiBaseURL if (isServer) { const host = req.headers.host apiBaseURL = process.env.NODE_ENV === 'development' ? `http://${host.replace(':3000', ':8000')}/api` : `https://${host}/api` } else { apiBaseURL = process.env.NODE_ENV === 'development' ? `http://${window.location.host.replace(':3000', ':8000')}/api` : `https://${window.location.host}/api` } // 更新local策略的所有端点 $auth.strategies.local.endpoints.login.url = `${apiBaseURL}/login` $auth.strategies.local.endpoints.logout.url = `${apiBaseURL}/logout` $auth.strategies.local.endpoints.user.url = `${apiBaseURL}/user` }
同样在nuxt.config.js的plugins里注册:
plugins: ['~/plugins/axios.js', '~/plugins/auth.js']
为了在本地测试子域名访问,需要修改本地Hosts文件,把租户子域名指向127.0.0.1:
- Windows:
C:\Windows\System32\drivers\etc\hosts - Mac/Linux:
/etc/hosts
添加以下内容:
127.0.0.1 tenant1.localhost 127.0.0.1 tenant2.localhost
这样你就可以通过http://tenant1.localhost:3000访问Nuxt应用,所有API请求会自动转发到http://tenant1.localhost:8000/api,完美适配django-tenants的多租户模式。
最后别忘了在Django那边做两件事:
- 配置CORS允许Nuxt的域名:开发环境允许
http://*.localhost:3000,生产环境允许https://*.example.com - 确保django-tenants的子域名路由配置正确,能识别
tenant1.example.com这类请求
这样整套配置就跑通了,不管是生产环境还是开发环境,都能自动适配不同租户的子域名~
内容的提问来源于stack exchange,提问作者edge

