JWT인증 인가) access token과 refresh token 어디에 저장.. 왜 저장되지 않는가 (해결완료)

horiz.d·2023년 5월 11일
0

PJ: Aight

목록 보기
3/17



문제!

왜 refresh Token은 저장되지 않는가?

network를 까보면 login의 set Cookie에 장고에서 설정해준 쿠키가 잘 들어있는 것을 확인할 수 있다. 하지만 warning표시를 확인해보니
This attempt to set a cookie via a Set-Cookie header was blocked because it had the "SameSite=Lax" attribute but came from a cross-site response which was not the response to a top-level navigation.라고 한다. 필시 이 이유로 차단됐을것이다.

local에서 돌릴 때 http로 테스트중일떈 비슷하게...did not have the secure라고 떠서 https환경이면 이건 해결되겠구나 해서 배포 갱신하고 배포로 확인한건데 이번엔 크로스사이트 응답이라고 차단된것
- 참고로 도메인이 같아도 (http <-> https) scheme이 맞지 않으면 cross-site라고 간주한다고..

어쨌든 장고에서 쿠키설정에 부여한 samesite 속성이 잘못된것이다. samesite는 None | Lax | Strict가 있는데 난 Lax를 골랐던 것.

  • None
    - 동일 사이트와 크로스 사이트 모두 쿠키 전송이 가능합니다.
    - SmaeSite를 None으로 설정할 경우 Secure 속성을 함께 추가해야 함
    - Secure속성이 추가된 쿠키는 HTTPS 프로토콜에서만 전송이 가능

  • Strict
    - 서로 다른 도메인에서는 쿠키 전송이 불가능해 집니다

  • Lax
    - Strict 설정에 일부 예외(HTTP get method/ a href/ link href)를 두어 적용되는 설정

원래는 Lax를 설정할 때, 쿠키를 받은 Next사이드부터 생각해서, Next 최상위 도메인 내의 하위 페이지를 돌아다닐 때 refresh token이 당연히 유지돼야지! 하지만 어느정도의 보안은 유지하자! 하는 생각으로 Lax를 골랐으나, 이것을 가장 처음 장고에서 설정하여 보냈기 때문에, 처음부터 잘못된것이지



이후, 몇번의 삽질을 하고 아래의 글을 참고하여
REF: https://brocess.tistory.com/263

구글에서 80버전의 크롬부터는 보안을 명분으로 samesite=None을 사용하지 못하도록 한다는 조치를 확인했고, 이에 대한 대안으로 samesite=None, secure을 함께 설정할 경우 사용할 수 있다는 사실을 확인하여 적용하였고 아래처럼 Network에서 set-cookie가 warn 없이 잘 전달되었음을 확인했다.



그러나!

cookies를 확인해보면 여전히 access token만 가지고 있고, refresh는 보이지 않는다. (참고로 access는 다른곳에 저장하도록 수정할것이다)

대체 왜..?



쿠키의 도메인이 브라우저 도메인과 일치하지 않을 때 저장되지 않을 수 있다는 사실을 확인했다. 따라서, 아래와 같이 장고 내 로그인 뷰에서 set_cookie시 domain을 설정해주었다.

response.set_cookie('refresh', str(refresh), 
                            domain="https://cmd8-nbo8d7c37-abizcho.vercel.app",
                            httponly=True # 스크립트상 접근불가
                            , samesite='Lax' 
                            , secure=True # 개발환경 테스트 False,
                            # Strict 모드에서는 같은 도메인 범위에서만 해당 쿠키를 사용, Lax는 사용자가 페이지 이동 시 혹은 Form을 통한 Get 요청 시에만 허용함
                            
                            )

하지만 이번엔

This Set-Cookie Domain Attribute Was Invalid With Regards To The Current Host Url. 이런 경고가 set_cookie에서 보여졌는데, 결국 추가적 조사 이후 서버(장고) 클라(넥스트)의 최상위 도메인을 일치시켜주지 않는 이상 해결되지 않는 문제인것으로 확인했다.

따라서, 1. 애초에 넥스트에서 refresh token을 set_cookie하는 방법(문제 없을까?) 2. 도메인을 일치시키는 방법(개발 시 ngrok으로 테스트 가능할듯)을 고민해봐야한다...


이후 하루정도 더 공부를 지속한 결과 어느정도 납득이 되는 또 다른 답을 얻은 것으로 보인다.

httpOnly, samesite=None, secure를 설정하였고, Client 브라우저의 네트워크 탭에 Set-Cookie는 보이지만 막상 실제 쿠키는 저장되지 않는 문제는, "secure이 True로 설정된 쿠키는 기본적으로 HTTPS 연결을 통해서만 전송되도록 브라우저에 지시"한다고 한다.

현재 내 장고서버는 로컬의 runserver로 구동되고 있고 http환경으로 돌아가고 있기 때문에, http 프로토콜로 전송을 보내는데 이 때문에 아무리 vercel상에서 https로 NEXT.JS가 배포되는 중이라고 하더라도, 애초에 http응답에서 담겨온 쿠키를 브라우저는 저장하지 않는것이다.

따라서, 나는 바로 다음 스텝으로 DRF를 배포하는 것을 최우선순위로 수행하여 인증로직이 정상적으로 작동하는지 직접 눈으로 확인하고자 한다.


해결완료되었다.

[AIGHT]브라우저에서 HTTP ONLY 쿠키 저장 성공 <-

profile
가용한 시간은 한정적이고, 배울건 넘쳐난다.

0개의 댓글