Post

HTTP 인증(Auth) 정의 및 방법

로그인/회원가입 등 유저 Auth에 대한 정의와 방법을 알아보자

HTTP 인증(Auth) 정의 및 방법

일반적인 HTTP 인증 프레임워크


유저가 로그인하여 마이페이지, 글 작성, 정보 확인 등을 하는 이유는 무엇일까??

궁극적으로 해당 서비스를 운영하는 서버 측에 저장된 중요한 리소스들을 얻기 위함이다. 당연히 아무나 이 리소스에 접근할 권한을 줄 수 없고, 리소스 접근에 허용 된 유저에게만 클라이언트(웹 브라우저, 모바일 앱)를 통해 인증을 거치고 리소스 접근을 허용해준다. 쉽게 설명하자면, 자신이 블로그 글을 작성했을 때 본인만 수정할 수 있어야 하는 이유를 놓고 보면 접근을 허용하도록 인증을 거치고 그 외 접근은 서버에서 거부를 해야할 것이다.

이에 대한 절차를 표준화한 것이 HTTP 인증 프레임워크 이다.

RFC 7235


RFC 7235HTTP 인증(HTTP Authentication) 에 대한 표준을 정의한 문서로, “클라이언트와 서버 간 인증이 필요한 경우 어떤 방식으로 동작해야 하는지” 를 설명한다.

핵심 내용은 다음과 같다.

  1. 인증 요청 방식 :
    • 유저는 잘못된 로그인을 시도하거나, 로그인 없이 인증이 필요한 페이지에 접근을 클라이언트에게 요청한다.
    • 클라이언트(웹 브라우저, 모바일 앱)는 유저의 요청대로 서버에 요청한다.
    • 서버는 보호된 리소스를 접근하려는 클라이언트에게 401 Unauthorized 응답과 WWW-Authenticate 헤더를 보낸다.
    • 서버와 인증을 하기를 원하는 클라이언트는 Authorization 헤더를 사용하여 인증 정보를 포함한 요청을 다시 보낸다.
  2. WWW-Authenticate 헤더 (서버 ➡️ 클라이언트) : 서버가 클라이언트에게 인증 방식 (ex. Basic, Bearer, Digest 등)을 알려주는 역할. 즉, 유저가 로그인에 실패했을 때 정확히 필요한 인증 방법이 무엇인지 알려준다.
    1
    2
    
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: Basic realm="User Login"
    
  3. Authorization 헤더 (클라이언트 ➡️ 서버) : 클라이언트가 서버에 인증 정보를 보내는 헤더.
    1
    
    Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
    
  4. Proxy-Authenticate 및 Proxy-Authorization 헤더 : 프록시 서버를 사용할 때 적용됨
    • Proxy-Authenticate : 프록시가 인증을 요구할 때 서버가 보내는 헤더. 2번의 WWW-Authenticate 와 동일한 목적이다.
    • Proxy-Authorization : 클라이언트가 프록시에 인증 정보를 보내는 헤더. 3번의 Authorization 과 동일한 목적이다.
  5. RFC 7235 기반 인증 방식
    • Basic : 사용자명과 비밀번호를 Base64 로 인코딩 하여 전송. 단, 보안 수준은 낮기 때문에 HTTPS 가 필수적으로 사용되어야 한다.
    • Bearer : JWT(JSON Web Token) 등을 사용한 토큰 기반 인증. 보안 수준은 높은 편이다.
    • Digest : 해시 기반 인증 (MD5 사용). 보안 수준은 MD5의 취약점 때문에 중간이다.
    • OAuth 2.0 : 회원가입 없이 Google, Naver, Kakao와 소셜 플랫폼에서 제 3자에게 토큰을 공유해주고 이를 기반으로 인증하는 방식. 보안 수준은 매우 높은 수준이다.
    • 그 외 HOBA, Mutual, Negotiate/NTLM, VAPID, SCRAM, AWS4-HMAC-SHA256 등 방식이 다양하지만 추가 설명은 생략한다.
  6. 접근 성공 시 상태 코드
    • 200 (OK) : 정상적인 요청 처리.
    • 201 (Created) : 새로운 리소스가 생성됨. (POST 요청 성공 시)
    • 202 (Accepted) :요청이 접수되었으나 아직 처리되지 않음 (비동기 작업)
    • 204 (No Content) : 요청이 성공했지만 반환할 컨텐츠가 없음 (DELETE 요청 후)
    • 206 (Partial Content) : 클라이언트 일부 데이터만 요청했을 때 (ex. 파일 다운로드 시 특정 범위 요청)
  7. 접근 거부 시 상태 코드
    • 400 (Bad Request) : 요청이 잘못됨. (ex. 문법 오류, 필수 파라미터 누락 등)
    • 401 (Unauthorized) : 요청된 리소스에 대한 인증 자격 증명이 없음. 보통 로그인이 필요한 상황 (WWW-Authenticate 헤더 포함하여 전달)
    • 403 (Forbidden) : 인증은 했지만 접근 권한이 없음. (ex. 관리자 전용 페이지)
    • 404 (Not Found) : 요청한 리소스를 찾을 수 없음.
    • 405 (Method Not Allowed) : 해당 리소스에서 허용되지 않는 HTTP 메서드 사용. (ex. GET만 가능한데 POST를 요청한 경우)
    • 407 (Proxy Authentication Required) : 프록시 서버에서 인증이 필요함.
    • 409 (Conflict) : 요청이 현재 리소스 상태와 충돌. (ex. 중복된 데이터 생성 시도)

대표적인 인증 방식의 구체적인 설명


몇 가지 대표적인 인증 방식에 대해 자세히 알아보자.

1. Basic 인증 방식

Basic 인증은 말 그대로 가장 기본적인 인증 방식이다. 인증 정보로 “ID”“비밀번호” 를 사용한다. 이를 “base64” 로 인코딩하여 문자열 Basic과 함께 Authrization 헤더에 담아 전달한다.

1
Authorization: Basic base64({USER_NAME}:{PASSWORD})

Basic 인증 방식의 가장 큰 장점이자 단점은 “간단함” 이다. ID와 비밀번호 외에 로그인 페이지나 별도의 인증 정보를 요구하지 않는다. 그러나 ID와 비밀번호를 서버에 저장해야 한다. 이는 유저가 많아지거나 서버를 찌르는 행위가 많아지면 서버의 리소스를 잡아 먹고 부담이 커지고, 저장된 유저 목록이 많아질수록 권한을 확인하는 시간이 길어지게 된다.

더불어 사용자 권한을 정교하게 제어할 수 없다. 유저에게 꼭 필요한 리소스에만 권한을 주는 게 좋은데, Basic 인증 방식은 세세하게 사용자의 권한을 설정하려면 추가 구현이 필요하다. 이는 복잡한 현대 IT 서비스에 정교한 인증 방식을 요구하는 시스템에 적합하지 않다.

2-1. Bearer 인증 방식

Bearer 인증 방식은 OAuth 2.0 프레임워크 에서 사용하는 토큰 인증 방식이다. “Bearer”는 “소유자”라는 뜻인데, “이 토큰의 소유자에게 권한을 부여해줘.” 라는 의미로 이름을 붙였다고 한다.

1
Authorization: Bearer <token>

Bearer token은 OAuth 프레임워크에서 Access token으로 사용하는 토큰의 유형이다. 기본적으로 내부 구조를 확인할 수 없는 비공개 형식의 토큰 (Opaque Token)을 사용하거나, JWT(JSON Web Token)을 사용하기도 한다. 이는 인증을 담당하는 서버에서 정의하기 나름이다. 중요한 것은 “Bearer 토큰은 클라이언트가 해석할 수 없는 형태여야 하고, 사용자의 정보를 전달해선 안된다.” 는 것이 핵심이다. 대신, “서버에서 클라이언트의 권한을 확인할 수 있는 메타데이터가 토큰에 인코딩되어 있어야 한다.” 이를 통해 서버에선 충분히 복잡한 알고리즘을 사용해서 토큰을 발급해야 한다.

Bearer 인증은 비교적 안전하고 확장이 쉽다. Bearer token을 쉽게 복호화할 수 없을뿐더러 OAuth 프레임워크는 SSL/TLS를 필수로 사용하기에 안전하다. 게다가 서버는 token의 리소스 접근 권한을 쉽게 철회할 수 있고, token의 유효기간을 설정할 수 있어서 안전하게 리소스를 보호할 수 있다.

또한, Bearer token 자체가 메타데이터를 가지고 있기 때문에 서버는 토큰을 발급만 하고 보관할 필요가 없다. 따라서 Basic 인증과 반대로 유저가 많을지언정 token을 검증하는 시간은 모두 동일하게 소요되고 서버의 부담도 줄어들며 여러 서비스와 서버에 토큰을 공유할 수 있기 때문에 확장성 또한 훌륭하다.

다만, Bearer token 역시 노출되면 다른 서비스에 악의적으로 접근할 수 있다. 하지만 서버가 OAuth 프레임워크에 정의된 보안 장치를 잘 구축하면 문제가 없고, 노출이 발견되면 즉시 해당 토큰의 권한을 철회할 수 있기 때문에 비교적 안전하다.

인증 방식보안확장성복잡성
Basic 인증쉽게 복호화할 수 있는 base64를 사용하고, 노출된 인증 정보를 철회할 방법이 없음사용자 정보를 서버에 저장하기 때문에 사용자가 많을수록 서버에 부담됨간단한 인증 방법이지만, 정교하게 권한을 제어하기 어려움
Bearer 인증충분히 복잡한 알고리즘으로 토큰을 발급하고, 토큰이 노출되면 권한을 철회할 수 있음Bearer 토큰이 메타데이터를 담고 있어서 사용자가 많아도 서버가 부담되지 않음정교하게 권한을 제어할 수 있고 유효기간, MFA 등 추가 장치도 연동할 수 있음

2-2. OAuth 2.0 프레임워크

요즘은 회원가입 절차 없이 Google, Naver, Kakao와 같은 소셜 계정으로 바로 이용할 수 있는 편리한 서비스가 많다. 이는 소셜 플랫폼에 있는 내 데이터의 일부를 제 3자의 서비스와 공유하는 것이다. 다양한 서비스 플랫폼의 각 서버 사이에 안전하게 데이터를 전송하기 위해 탄생한 것이 “OAuth 프레임워크” 이며, OAuth는 제 3자의 클라이언트에게 보호된 리소스를 제한적으로 접근하게 해주는 프레임워크이다.

OAuth 프레임워크는 다음과 같이 구성되어 있다.

  1. “리소스 소유자” : 유저
  2. “클라이언트” : 유저의 정보를 접근하는 제 3자의 서비스 (웹 브라우저, 모바일 앱)
  3. “인증 서버” : 클라이언트의 접근을 관리하는 서버
  4. “리소스 서버” : 리소스 소유자의 데이터를 관리하는 서버

리소스 소유자(유저)의 동의가 확인되면 인증 서버는 클라이언트에게 Access Token을 발급해준다. 클라이언트는 발급된 Access Token을 사용해서 리소스 서버에 보호된 데이터를 불러온다.

Session based authentication : 세션(Session) 방식과 쿠키(Cookie) 인증


웹 프론트엔드 개발자라면 반드시 알아야 할 인증 방식을 짧게 설명하고자 한다. 기본적으로 HTTP 통신은 지속적인 연결을 유지하지 않고 일회성의 요청/응답 패턴을 사용한다. 즉, 각 요청마다 어떠한 연관 관계도 없으며 과거에 대한 정보를 전혀 담지 않는 “Stateless(무상태)” 라고도 한다. 그렇기 때문에 유저는 방금전에 리소스를 요청할 때 ID와 Password를 보냈음에도 불구하고 다음 요청마다 계속 ID와 Password를 같이 보내 필요한 서버의 리소스를 요청해야할 것이다. 유저 입장에서도 불편하지만 보안 측면에서도 매우 취약하다는 단점이 있다.

이러한 HTTP 특성에서 매 요청 간의 연관 관계를 만들기 위해 나온 것이 바로 “세션(Session)” 방식이다. 세션은 컴퓨터에서만 사용하는 용어가 아니다. 일상적으로 회의, 강연, 통화, 채팅 등을 세션이라고 칭하며 공통적으로 “한번 연결되면 해당 연결이 지속된다.” 라는 특징이 있다. HTTP 통신에서의 세션 역시 동일한 뜻을 지닌다. 무상태 특성을 지닌 HTTP 통신 환경에서 어떤 토큰 하나로 클라이언트와 서버가 매번 불필요한 user credential(ID, PW) 검증을 대체한다는 점이 핵심이다.

위에서 칭한 토큰을 우리는 통상적으로 “쿠키(Cookie)” 라고 한다. 서버는 로그인을 시도한 유저의 고유값을 부여해서 세션 저장소에 저장하고, 세션이 저장 되었다는 정보를 쿠키로 만들어서 클라이언트(웹 브라우저)에 보낸다. 클라이언트는 서버로 부터 받은 쿠키를 로컬 스토리지, 세션 스토리지, 혹은 JS 내부 변수 등에 저장하고 HTTP 요청 시마다 쿠키를 꺼내서 헤더에 담아 보낸다. 서버는 헤더 안에 쿠키를 열어 세션을 저장한 저장소에서 쿠키에 담긴 정보와 일치하는지 확인 후 원하는 리소스를 클라이언트에게 전달하게 된다.

결론적으로, “쿠키는 인증을 거치는 매개 수단이다.” 유저의 ID, PW와 같은 어떤 정보를 가지고 있다기 보다는 “정보를 보여줄 수 있는 열쇠 같은 것” 이라고 생각하면 된다. 그러니 쿠키에 담긴 HTTP 요청이 중간에 탈취되더라도 쿠키 자체는 유의미한 값이 없으니 ID/PW를 그대로 담아서 보내는 인증보다는 안전하다고 할 수 있다.

쿠키를 탈취당할 위험 요소를 줄이기 위해 쿠키 안에 정보를 읽기 힘들게 하거나 반드시 “HTTPS” 를 사용한다.

Token based authentication : JWT(JSON Web Token)


Token based authentication 의 대표적인 방식인 JWT이다.

우선, JWT를 만들기 위해 다음과 같은 세 가지가 필요하다.

  1. Header : 정보를 암호화 할 방식, 타입 등이 들어간다.
  2. Payload : 서버에서 보낼 데이터가 들어간다. 일반적으로 유저의 고유 ID값, 유효기간 등이 들어간다.
  3. Verify Signature : base64 방식으로 인코딩한 Header, Payload, SECRET KEY를 더한 후 서명된다.

따라서 최종적으로 Encoded Header + "." + Encoded Payload + "." + Verify Signature 가 된다.

그렇다면 어떻게 인증에 사용될까?

위에서 설명한 세션 방식과 동일하게 유저가 로그인을 하면 서버에서는 인증을 한 후 JWT의 긴 문자열을 클라이언트에게 전송한다. 클라이언트는 취향에 따라 변수 혹은 스토리지에 저장한 후 다음 HTTP 요청 시에 Header에 JWT를 포함하여 함께 전송한다. 마찬가지로 서버에서는 헤더의 JWT를 열어 정보가 일치하고 만료되지는 않았는지 검사한 후 검증이 끝나면 필요한 리소스를 클라이언트에게 전달해준다.

이 역시 페이지 요청할 때 마다 로그인 했다는 정보가 JWT로 Header에 담겨서 오기 때문에 “굳이 서버가 로그인 상태를 저장하고 있을 필요가 없다는 특징이 있다.”

다만 한번 발급 된 JWT는 만료가 되지 않는 이상 돌이킬 수 없다. 세션의 경우 쿠키를 지워버리면 되지만, JWT는 한번 발급되면 만료될 때 까지 계속 사용이 가능하다. 따라서 악의적인 사용을 방지하기 위해 Access Token의 유효 기간을 짧게 설정하고 대신 Refresh Token이라는 새로운 토큰을 발급한다.

도움글


HTTP 인증, MDN

Basic 인증과 Bearer 인증의 모든 것, 토스 페이먼츠 개발자 센터

Authentication 인증구현 방법 세 가지! (세션, JWT, OAuth)