HTTP - 401과 403

on under http
1 minute read

API의 권한에 대해 테스트 코드를 작성하는 도중 뜻하지 않은 결과의 반환(401, 403)으로 401와 403에 대한 차이를 알아보고 그 결론을 기록합니다.

참조 https://leastprivilege.com/2014/10/02/401-vs-403/

우선 권한 관련 테스트 코드입니다.

def test_authorization_is_enforced(self):
     new_client = APIClient()
     res = new_client.get('/posts/', kwargs={'pk':2}, format="json
     self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)

임의의 게시물을 조회할때 권한이 없다면 403 에러가 발생할 것을 기대한 코드입니다. 하지만 테스트를 실행하면

======================================================================
FAIL: test_authorization_is_enforced (blog.tests.ViewTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "../tests.py", line 42, in test_authorization_is_enforced
    self.assertEqual(res.status_code, status.HTTP_403_FORBIDDEN)
AssertionError: 401 != 403

response는 401 에러를 발생하여 테스트를 통과하지 못합니다.

401은 허가되지 않음을 의미하고, 403은 금지됨을 의미합니다…만 HTTP1.1 에서는 명확하게 구분하지 않는다고 합니다. Web API의 속성은 항상 401을 내보낸다고 합니다.

쉽게 정리하자면, 401은 익명의 사용자, 403는 로그인은 하였으나 권한이 없는 사용자 정도로 구분하면 될 것 같습니다.

위 내용을 기준으로 새로운 테스트 계정을 만들어서 실행해 본 결과

Unauthorized: /posts/1/
[30/Dec/2018 09:04:13] "GET /posts/1/ HTTP/1.1" 401 5119 // 로그인 전
Forbidden: /posts/1/
[30/Dec/2018 09:04:16] "GET /posts/1/ HTTP/1.1" 403 6504 // 로그인 후

로그인 여부에 따라 401과 403이 차이가 나는 것을 확인하였습니다.

위 테스트 코드에도 로그인을 다시 하나하나 적용해 보았지만, 401만 발생되었습니다. 일단 API는 401만 내보내는 것 같습니다.

다른 테스트 코드(권한이 있어야만 업데이트가 가능한 테스트)를 수정한 결과 403이 잘 뜨는 것을 확인했습니다. API라고 401만 반환한다는 것은 틀린 말이네요.

woohyun씨 언제나 ㄱㅅ.

http
comments powered by Disqus