Nuxt.js Auth 模块错误(其实是 Docker Links 的问题) | GGAMI.NET
首页 / 开发 / Nuxt.js Auth 模块错误(其实是 Docker Links 的问题) 不是……明明记得之前好像还好好的……
在 Nuxt.js 中通过 Auth 登录后,刷新页面时突然报错了。
[Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render.
不,准确地说,刷新时 SSR 服务端渲染会认为没有 Auth,所以会以 false 状态加载;而客户端获取到用户 ID 后,会以 true 状态输出,因此两边渲染出来的内容不一样……
我觉得上面这个 issue 说的应该没错,但怎么都解决不了……不是,我明明在配置里设了
localStorage: null,记得之前明明生效过,可现在又不行了。唉……这到底要我怎么办啊……明明之前好像一点问题都没有,突然就出了这种错误……
唉……你到底是哪里出了问题啊……
唉,我刚刚才把 Docker 都配置好,解决了刷新令牌和令牌认证的部分……
正准备开始做管理页面……结果这下根本没法继续了……
真不知道为什么 Nuxt.js 的 Auth Module 用起来这么难……(烦死了……)
有时能用,有时又不行……Windows 下明明没问题……换到 Docker 又不行了……哈哈,到底是什么原因我也不知道……
auth._token.local Bearer%20eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkuY29pbm5ldC5sb2NhbGhvc3RcL2FwaVwvdjFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNTY2MzM4MDEzLCJleHAiOjE1NjYzMzgzMTMsIm5iZiI6MTU2NjMzODAxMywianRpIjoieHNJcllscXFDUGhJdFI5dCIsInN1YiI6MSwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyIsImVtYWlsIjoiYWxjbHNAbmF2ZXIuY29tIiwibmFtZSI6Ilx1YzdhY1x1YzEzMVx1Yzc3NCIsIml2ZSI6dHJ1ZSwidHlwIjoxLCJybCI6MX0.52w9gOwexkWexQCacC2ietHdKTwltqC2T1MZ7cwKjVE
登录后,这个值就会被保存起来。然后假设刷新页面时,这个 Cookie 值也会一起发送;如果有这个 Cookie 值,服务端就会在 nuxtServerInit 中通过
来调用并获取值,然后保存起来。保存到 Auth/user 后就会立即输出……
这样一来,服务端渲染时也会收到有这个值并将其输出,客户端也不会有问题。
不过,如果服务端渲染时调用的 Token 失败了,客户端也会再尝试一次……
那么,为什么 Docker 里无法调用呢?
首先,我通过 Traefik 用 http.routers 注册了 Host,也就是访问域名。
然后把 Nuxt.js 的 backend.port 设为 3000,这样访问 域名:80 时,就会连接到对应容器的 3000 端口。
我觉得,Docker 里始终无法得到 true、而是得到 false 的原因,可能是刷新并连接到 Nuxt Docker 容器时,Header 中没有一起发送 Cookie 值。
除此之外就没有别的可能了……
那么我接下来要做的就是检查 Docker 通过 Traefik 调用时,Cookie 值是否也会一起发送……
唉……我在 GitHub issue 里求助了……但……什么都没有……真的什么都没有……感觉这个模块本身就不怎么受欢迎……今天熬了一整晚,不停地在 Docker 和 Windows 之间切换,时间全耗在这上面了……这肯定是 Traefik 的 Cookie 部分出了问题……我现在就去找原因……一定要解决了再睡……
啊……Authorization 里确实正确地带上了 Bearer……
我好像知道原因了……我找到了……我搜了太多东西……
axios 的 URL 错了……为什么呢……
本来 Docker 容器网络就只通过一个叫 frontend 的 bridge 连接……我却用后端 Host 来调用 URL,所以才调用不了啊!!!!!!
这绝对有 20000% 的把握……API URL 必须设为 Docker network 地址……
好……那么正常提供服务时可以从外部访问,所以即使使用 URL 也会正常……
但是在 DEV 环境中是 localhost……无法从外部访问……所以必须让容器之间互相连接吗??Traefik 会提供这种功能吗……?得查查看……
也就是说……SSR(Docker 容器)无法访问 api.dev.localhost。
但客户端是在主机上运行的,所以我设置了让它能通过 Traefik 连接 api.dev.localhost……
所以 Docker 服务端无法调用 api.dev.localhost,才会一直把会话当成已经失效……
总之,这样一来,nuxt.config.js 文件里的
baseURL 也不用修改了……
唉……这个问题让我从凌晨 1 点折腾到早上 8 点……不过还好,解决了就好……
总之……到今天为止,Laravel Backend 和 Nuxt.js Frontend 都已经 Docker 化了……
(呼……睡一觉起来之后,应该还得处理刷新令牌之类的东西……)
感觉 SSR 在刷新页面时,服务端要加载一次,客户端也要加载一次,最后得做两份……头都大了……唉……
如果这样设置,无法通过令牌获取 payload 时,就会直接把令牌清掉。(也会让客户端不再尝试)
我倒是有个自己设想的刷新方法……
开启 resetOnError 选项……然后在后端刷新时,直接换成新的令牌,同时取回数据,并立即注册令牌……
那客户端这边要怎么处理呢……?