Next-auth登录Django时Axios报connect ECONNREFUSED ::1:8000错误求助
技术栈
- 后端:
django(使用dj_rest_auth实现认证) - 前端:
nextjs(使用next-auth处理认证,环境变量配置无误) - 系统:Debian 12 - bookworm
- 依赖:
redis、memcached、rabbitmq运行在LXD - Ubuntu 22.04容器中
问题概述
本地运行nextjs(13+)+django(4.2+)应用,正在添加认证功能,采用next-auth(4.22+)处理认证流程。登录时触发错误AxiosError: connect ECONNREFUSED ::1:8000,其他axios请求均能正常响应,仅登录请求失败。此前使用Ubuntu 23.04无此问题,切换到Debian 12后首次遇到该错误,已尝试相关解决方案但未解决。
错误信息
{ error: AxiosError: connect ECONNREFUSED ::1:8000 at AxiosError.from (file:///home/yuri/Coding/pos/frontend/node_modules/axios/lib/core/AxiosError.js:89:14) at RedirectableRequest.handleRequestError (file:///home/yuri/Coding/pos/frontend/node_modules/axios/lib/adapters/http.js:591:25) at RedirectableRequest.emit (node:events:514:28) at eventHandlers.<computed> (/home/yuri/Coding/pos/frontend/node_modules/follow-redirects/index.js:14:24) at ClientRequest.emit (node:events:514:28) at Socket.socketErrorListener (node:_http_client:501:9) at Socket.emit (node:events:514:28) at emitErrorNT (node:internal/streams/destroy:151:8) at emitErrorCloseNT (node:internal/streams/destroy:116:3) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) { port: 8000, address: '::1', syscall: 'connect', code: 'ECONNREFUSED', errno: -111, config: { transitional: [Object], adapter: [Array], transformRequest: [Array], transformResponse: [Array], timeout: 0, xsrfCookieName: 'csrftoken', xsrfHeaderName: 'X-CSRFToken', maxContentLength: -1, maxBodyLength: -1, env: [Object], validateStatus: [Function: validateStatus], headers: [AxiosHeaders], baseURL: 'http://localhost:8000', withCredentials: true, paramsSerializer: [Object], method: 'post', url: '/api/auth/login/', data: '{"username":"yuri","password":"yuri","redirect":"false","csrfToken":"80d0b198ee09f1abc790d722d42e6fa48a0e38c78a77d4e7c4bd340c9cbb9636","callbackUrl":"http://localhost:3000/auth/sign-in?from=%2Fprofile","json":"true"}' }, request: Writable { _writableState: [WritableState], _events: [Object: null prototype], _eventsCount: 3, _maxListeners: undefined, _options: [Object], _ended: false, _ending: true, _redirectCount: 0, _redirects: [], _requestBodyLength: 216, _requestBodyBuffers: [Array], _onNativeResponse: [Function (anonymous)], _currentRequest: [ClientRequest], _currentUrl: 'http://localhost:8000/api/auth/login/', [Symbol(kCapture)]: false }, cause: Error: connect ECONNREFUSED ::1:8000 at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1495:16) { errno: -111, code: 'ECONNREFUSED', syscall: 'connect', address: '::1', port: 8000 } } }
Iptables配置
yuri@bookworm ~$ sudo iptables -L [sudo] password for yuri: Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination
/etc/hosts配置
127.0.0.1 localhost 127.0.1.1 bookworm # The following lines are desirable for IPv6 capable hosts ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters
故障原因
核心问题是Debian 12与Ubuntu的IPv6解析优先级差异:
Debian 12默认优先将localhost解析为IPv6地址::1,但你的Django服务仅绑定了IPv4的127.0.0.1端口8000,未监听IPv6的::1端口。而NextAuth发起的登录请求会遵循系统解析优先级走IPv6,导致连接被拒绝;其他Axios请求可能因直接使用127.0.0.1或服务端兼容配置,仍能通过IPv4正常连接。
解决方案
方案1:让Django同时监听IPv4和IPv6
启动Django时指定绑定地址为::(同时支持IPv4/IPv6):
python manage.py runserver ::8000
若使用生产环境WSGI服务器(如gunicorn),同样指定绑定地址:
gunicorn your_project.wsgi:application --bind ::8000
方案2:调整系统解析优先级,优先使用IPv4
编辑/etc/gai.conf,取消以下行的注释:
# precedence ::ffff:0:0/96 100
修改后系统会优先将localhost解析为127.0.0.1,强制请求走IPv4。
方案3:修改NextAuth的API地址为IPv4格式
直接将前端配置中的baseURL从http://localhost:8000改为http://127.0.0.1:8000,强制登录请求走IPv4。
验证方法
用curl分别测试IPv6和IPv4连接:
# 测试IPv6连接 curl -g http://[::1]:8000/api/auth/login/ # 测试IPv4连接 curl http://127.0.0.1:8000/api/auth/login/
若IPv6请求返回连接拒绝、IPv4请求正常,即可确认问题根源。
内容的提问来源于stack exchange,提问作者Zkh

