swsnu / swppfall2019

31 stars 23 forks source link

[HW3] Forbidden (CSRF cookie not set.) 오류 #149

Open iamsungyeonjoo opened 4 years ago

iamsungyeonjoo commented 4 years ago

안녕하세요 조교님 제목에 나와있는 오류를 해결하는데 어려움을 겪어 질문하게 되었습니다.

제가 아래의 순서대로 진행했을 때, api/article 에 post request를 보내면 제목에 명시한 오류가 뜹니다. (*3. 에서 혹시 몰라 새로운 토큰을 받아서 해봐도 같은 문제가 발생합니다.)

  1. api/token/에 get을 보내서 토큰을 받는다.
  2. 헤더에 복사한 토큰을 넣어주고 api/singin/ 으로 로그인을 한다.
  3. 이때 생긴 session id 를 복사한다.
  4. api/article/ 에서 post를 보내기 전에, Cookie : sessionid=~~~~; (2.에서 복사한 session id 넣어준다) X-CSRFTOKEN은 0.에서 받았던걸 그대로 넣어준다.
  5. send를 누른다.

이 순서대로 했는데 아래와 같은 오류가 뜹니다... view 로직이 잘못 됐나 싶어서 @ensure_csrf_cookie를 decorator에 추가해서 확인해봤는데 원하는 동작은 다 잘 하는걸로 확인이 되었습니다. image

혹시 확인해보아야할 부분이 있다면 조언 부탁드립니다.

ktaebum commented 4 years ago

145 #146 이랑 비슷한 문제인 것 같습니다.

signin을 하시면 csrf 토큰이 새로 나오기 때문에 그 때 나온 걸로 바꿔서 사용하시면 아마 될 거라고 생각합니다

저 순서 중에서 1에서 바뀐 토큰으로 변경하고 해보시길 추천드립니다.

아 3에서 새로운 토큰을 받아도 문제가 되는 거군요

iamsungyeonjoo commented 4 years ago

토큰이 문제가 생기는 경우에는 incorrect token 이런식으로 나오는데 저같은 경우는 not set이 떠서 헷갈렸습니다.

ktaebum commented 4 years ago

저 403이 반환되는 이유는 우선

csrf middleware가 https://docs.djangoproject.com/en/2.2/_modules/django/middleware/csrf/ 에서

REASON_NO_CSRF_COOKIE = "CSRF cookie not set."
...
            csrf_token = request.META.get('CSRF_COOKIE')
            if csrf_token is None:
                # No CSRF cookie. For POST requests, we insist on a CSRF cookie,
                # and in this way we can avoid all CSRF attacks, including login
                # CSRF.
                return self._reject(request, REASON_NO_CSRF_COOKIE)

일 때, 즉 request META 데이터에 CSRF_COOKIE가 없을 때긴 한데

저 데이터는 request가 들어오면

    def process_request(self, request):
        csrf_token = self._get_token(request)
        if csrf_token is not None:
            # Use same token next time.
            request.META['CSRF_COOKIE'] = csrf_token

request로부터 긁어와서 저장이 되어야 하는데 그 부분에 문제가 있는 것 같습니다.

ARC request header에서 cookie에 csrftoken이 잘 들어와 있나 확인을 먼저 해보는 게 좋을 것 같습니다

그와 별개로 view에선 signin과 auth 체크가 잘 구현되어 있는지 확인해보는 것도 좋을 것 같습니다. 그리고 signin하고 그 때 바뀐 토큰을 사용하시구요