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 한 확인을 할 수 있다.
•
expired 된 토큰이거나 잘못 보낸 토큰이라면 401을 반환하고, scope 를 벗어났다면 403을 반환
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.
[이 문서](https://tools.ietf.org/html/rfc6750)에 위와 같이 서술되어 있다. 게다가 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 이라 한다.
•
expired time: token 은 client 에 발급되면 인증이 되기 때문에 만료 시간을 정해진 시간이 경과할 때 까지 요청이 없거나, 요청이 있어도 토큰을 다시 받아야 한다. 정해진 시간이 지나면 그 token 은 의미가 없어진다.
•
malformed token: token 을 생성하는것은 JWT나 sha2 등 다양한 방법이 있지만, 글자를 잘못 쓰거나 전달 과정에서 실수가 발생하여 오타가 포함된다면 이 토큰을 malformed token 이라 한다.
2.
insufficient scope: 부족한 권한(부족한 범위)
•
user model 을 설계할 때 다양한 권한을 만든다. 관리자, 에디터, 사용자 등등.. 이 때, 에디터는 권한이 있지만 사용자에겐 권한이 없는 경우가 있다. 카페 같은 곳의 회원 등급과 같다고 생각하면 되겠다.
위에서 인용한 IETF Internet Engineering Task Force 는 권위 있는 기관이다. 인터넷 안에서 표준을 정하고 유지하며, 다양한 기준을 제시해 어플리케이션을 개발 할 때 혼란을 방지하는 든든한 기둥의 역할을 한다.