Nuxt.js Auth Module 에러 (사실은 Docker Links 문제)

Updated on

아니.. 분명 잘 됬던거 같은데..
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 된 상태로 로드 되는데, 클라이언트에서는 유저 아이디를 받아와서 true 로 출력하면서, 서로 렌더링되는게 다른거다….

https://github.com/nuxt-community/auth-module/issues/425

내 생각에는 위 이슈가 맞는거 같은데, 도저히 해결이 안된다.. 아니 분명히 설정 값에
localStorage: null 했는데,, 분명 적용 됬던거 같은데 또 안된다. 하아….. 이걸 도대체 어쩌자는거냐.. 분명 아무런 문제 없었던거 같은데, 갑작스럽게 이런 에러가 발생하는거 같다..

하.. 도대체 뭐가 문제냐 넌……
하아,, 이제 막 도커 세팅 다 끝내서,, 리프레쉬 토큰하고, 토큰 인증 부분 해결하고서..
관리자 페이지 작업좀 들어가려고 했는데.. 이건 뭐.. 작업을 할 수가 없다..

왜 이렇게도, Nuxt.js의 Auth Module을 사용하기도 어려운지 모르겠다.. (짜증….)

됬다가 안됬다가.. 윈도우에서는 문제 없이 되는데.. Docker로 넘어가면 또 안된다.. ㅋㅋ 도대체 뭐가 원인인지 모르겠는데..

일단… Auth 모듈을 보자..

auth._token.local Bearer%20eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hcGkuY29pbm5ldC5sb2NhbGhvc3RcL2FwaVwvdjFcL2F1dGhcL2xvZ2luIiwiaWF0IjoxNTY2MzM4MDEzLCJleHAiOjE1NjYzMzgzMTMsIm5iZiI6MTU2NjMzODAxMywianRpIjoieHNJcllscXFDUGhJdFI5dCIsInN1YiI6MSwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyIsImVtYWlsIjoiYWxjbHNAbmF2ZXIuY29tIiwibmFtZSI6Ilx1YzdhY1x1YzEzMVx1Yzc3NCIsIml2ZSI6dHJ1ZSwidHlwIjoxLCJybCI6MX0.52w9gOwexkWexQCacC2ietHdKTwltqC2T1MZ7cwKjVE

로그인하면, 해당 값이 저장 된다. 그리고 새로고침을 했다 치면, 해당 쿠키값이 함께 날아가는데, 해당 쿠키 값이 있으면, 서버단에서 nuxtServerInit 에서

user: { url: 'auth/~~~', method: 'get', propertyName: 'payload' },

로 호출해서, 값을 받아와서 저장한다음에. Auth/user에 저장 후에 바로 뿌려준다..
그러면, 서버렌더링때에도, 있다고 받아서 출력하는거고, 클라이언트에서도 문제 없다.

하지만, 여기서 서버렌더링에서 호출한 Token 값이 실패하면, 클라이언트에서도 한번 더 시도하게 된다..

자.. 그러면 왜 도커에서는 호출을 못하는걸까 ?
일단 나는 Traefik 을 통해서 http.routers 로 Host를 등록했다. 접근 도메인
그리고, nuxt.js의 backend.port를 3000으로 설정해줘서, 도메인:80 으로 접근하면, 해당 컨테이너의 3000 포트로 연결되게 했다.

여기서, 도커에서만 절대 true가 안나오고 false 가 나오는 이유는 해당 Nuxt 도커 컨테이너를 새로고침해서 연결할때, Header에 Cookie값이 같이 전송 안되기 때문일 것 같다.

req.headers.cookie

이거 말고는 답이 없다…
그러면 내가 해야할 건.. 도커에서 Traefik로 호출할때 Cookie 값이 같이 전송되느냐를 체크 해봐야한다..

하.. 이거 뭐 github 이슈에 도와달라 적고 하고 했는데.. 뭐… 없다… 그냥 없다… 애초에 이 모듈 자체가 인기가 없는거 같다… 오늘 하루 밤 새면서 계속 도커 켰다 윈도우 켰다 하느라 시간 다 보냈는데.. 이건 무조건 Traefik에서 Cookie 부분일거다… 지금부터 찾으러 간다.. 꼭 해결하고 잔다..

아… Authorization 에 Bearer로 잘 들어간다…
이유를 알 것 같다… 알아 냈다.. 하도 많은 것들을 검색했다..
axios url이 잘못된거다.. 왜냐고..
애초에 도커 컨테이너 네트워크는 frontend 라는 브릿지 하나로 연결되어 있는데.. URL을 백엔드 Host로 호출 하니까 호출이 안되는거다 !!!!!!!!!!!

이거 20000%다….. API url을 docker network 주소로 설정 해야된다..

자… 그렇다면, 정상 서비스할때에는 외부접속이 가능하므로, URL을 해도 잘 될거다..
하지만, DEV환경에서는 localhost.. 외부접속이 안되므로,, 컨테이너끼리 연결해줘야하는건가 ?? Traefik에 제공하나..? 찾아봐야겠다..

그러니까.. SSR에서 (도커 컨테이너) 접근이 안되는거다. api.dev.localhost 에..
하지만, 클라이언트는 호스트이므로, Traefik으로 api.dev.localhost 연결이 가능하게 해둔거고..

그러니 도커 서버단에서는 api.dev.localhost 호출이 안되니, 자꾸 세션이 죽은거로 처리되는거다..

https://docs.docker.com/compose/compose-file/#external_links

그래서 처리한 방법은..
docker-compose 파일에 links 시켜버렸다.
links:
- backend:api.dev.localhost

그렇게.. nuxt.js 에서 ping api.dev.localhost 가 문제 없이 간다 !!
external_hosts로 가능할까 했는데.. 그냥 links로 처리했다..
신기한건, hosts에 등록되어 있지 않는데도 된다는거다.. 왜지..?

root@3bd110d9aaef:/app# cat /etc/hosts
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.22.0.4      3bd110d9aaef

어쨌든, 이렇게 하게 되면. nuxt.config.js 파일에서의

  axios: {
    baseURL: 'http://api.dev.localhost/api/v1',
  },

baseURL 또한 수정하지 않아도 된다..
하… 이 문제로 정작 새벽 1시부터 8시까지…. 고생을 했다… 그래도 다행인건, 해결 했다는게 다행이다…

그런데.. 또 다른 나중에 분명 또 다른 문제가 발생할 것(?) 같기도 하다..
https://github.com/nuxt-community/auth-module/issues/258

일단.. 오늘까지해서 Laravel Backend, Nuxt.js Frontend 해서… 도커화 시켰다…..
(후우.. 이제 자고 일어나면, 리프레쉬 토큰 기타 등등 처리해야할 듯 싶다..)
이게 SSR은 새로고침했을때, 서버에서 불러오는거 하나, 클라이언트 하나, 결국 두개를 만들어야 되는구나 싶기도 함…. 머리 아프네.. 흠..

그리고 추가적으로… Auth Config 에서

'resetOnError': true,

처리할 경우, 토큰으로 payload 하지 못하면, 그냥 바로 토큰을 날려버린다. (클라이언트에서도 시도하지 않게 만듬)

내가 생각하고 있는 리프레쉬 방법이 있긴 한데…
resetOnError 옵션 켜고,, 백엔드에서 새로고침했을때 그냥 바로 새로운 토큰 값으로 바꾸는 동시와 데이터를 받아와서, 바로 토큰 등록 시켜주고 싶다..
그리고 클라이언트에서는 어떻게 처리하지..?