cleanUrl: /posts/401-vs-403

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e9dace69-dd56-4a27-94ac-6f74b6d37864/http-status-code.jpg

HTTP 스펙에서 401 (unauthorized) 와 403 (forbidden) 에 대해서 무엇을 선택하느냐는 세심하게 살펴보지 않는다면 늘 햇갈리는 이슈였다.

문제현황

제휴사로 API를 제공하면서 http header 에 Authorization 에 토큰 방식으로 인증된 사용자인지 확인하는 토큰을 추가해야 하는 상황이다.

그런데 token 이 없는 유저가 요청했을 때 혹은 제공된 토큰이 아닌 오타와 같은 토큰으로 요청했을 때 어떤 status code 를 반환 할지에서 고민이 들었다.

spec 을 정확하게 살펴보지 않고서 처음엔 너는 토큰이 없기 때문에 forbidden 이 맞아 라고 생각했다.

하지만, 이 두 코드는 너에게 토큰이 없거나 유효하지 않는 토큰으로 전송한 상황이야너가 올바른 토큰을 보낸건 맞지만, 이 entity 는 너의 권한에 제공되지 않아 라고 분명히 구별할 수 있다.

예를들면

  1. Form 을 통해 인증 절차를 진행한다면, 401은 로그인 페이지 (302)로 유저의 페이지를 돌려준다. (특히 우리 앱의 유저인지 알 수 없는 익명의 사용자일 때) 그리고, 이미 authenticated 된 유저인데 인증 절차에 문제가 발생하여 로그인 페이지로 보여준다면 직관적인 UX가 아니게 된다. 이럴땐 에러가 로깅되고 유저에게는 Error page 를 보여주는것이 올바르다.
  2. API 에서 token 으로 인증을 할 때, 서버는 expired token 인지 혹은, 유저가 갖고 있는 token 에 합당한 scope로 요청한 것인지 확인해야 한다. Bearer token usage를 참고하면, 이에 해서 매우 clear 한 확인을 할 수 있다.

Invalid_token

The access token provided is expired, revoked, malformed, or invalid for other reasons. The resource SHOULD respond with the HTTP 401 (Unauthorized) status code. The client MAY request a new access token and retry the protected resource request.

insufficient_scope

The request requires higher privileges than provided by the access token. The resource server SHOULD respond with the HTTP 403 (Forbidden) status code and MAY include the "scope" attribute with the scope necessary to access the protected resource.

이 문서에 위와 같이 서술되어 있다. 게다가 HTTP 1.1 spec 은 최근에 401과 403에 대해 다시 정의 되었다

The 401 (Unauthorized) status code indicates that the request has not been applied because it lacks valid authentication credentials for the target resource. The server generating a 401 response MUST send a WWW-Authenticate header field (Section 4.1) containing at least one challenge applicable to the target resource.

A server that receives valid credentials that are not adequate to gain access ought to respond with the 403 (Forbidden) status code.

결론

401 에러는 유효하지 않은 인증 토큰일 경우 반환하고 403 에러는 토큰은 있지만, 그 토큰을 받은 유저가 scope 가 부족할 때 반환하는 것이다.

용어 정리

  1. invalid token : 유효하지 않은 토큰이며 다음과 같은 상황일 때 invalid token 이라 한다.