[백엔드 로드맵 - API] Authentication

Sierra·2022년 10월 3일
0

Backend-Roadmap

목록 보기
37/43
post-thumbnail

Intro

필자가 어느 시점부터 회사를 다니고 있어서 로드맵 시리즈의 진행이 많이 늦어지고 있다.
올해 안에는 어떻게든 마무리 짓고 한번 더 손보고자 하는 게 목표다...

이번 포스팅의 주제는 Authentication이다. 한번 쯤은 주니어 백엔드 개발자를 괴롭힐 법한 문제고 절대 몰라서는 안되는 주제라 생각한다. 프로그래머라면 한 번 쯤은 겪게되는 인증 관련 문제들을 이해하기 위해서 반드시 인증에 대한 지식이 필요하다.

Authentication?

영어 단어 그대로 해석 해 보면 인증이다.
어떤 상황에 많이 쓰일까? 정말 단순하게 생각 해 보면 로그인 과정에서 쓰인다.

특정 서비스에 어떠한 사람이 접근하려고 한다. 하지만 모두의 접근을 허용 할 것인가?
개발자의 판단에 따라 다르겠지만, 만약 권한이 존재하는 사용자에게만 접근을 허용하려면 어떻게 해야 할까?

Authentication 에 대한 고려 없이 만약 API 서버를 구축했다면, 어느 누구든 API 를 사용할 수 있게 된다. 상황에 따라 그렇게 해야 할 경우도 생기겠지만 OpenAPI 서비스를 사용 해 본 사람은 알겠지만 Private Key를 발급받아 인증을 거친 후 사용하는 경우가 상당히 많다는 것을 알 수 있다. 상황에 따라 물론 다르겠지만, 특정한 데이터를 제공하는 API 에 따라 악용될 것을 방지하기 위해 Private Key를 제공하여 인증 된 사용자에게만 서비스를 제공하는 경우가 있다. 이런 경우에는 아마 JWT 방식의 Authentication 을 사용했을 것이다.

Authentication VS Authorization

단어 뜻 차이 정도의 차이만 존재한다고 보면 된다.

Authentication 은 우리가 로그인 할 때 이루어진다 생각하면 된다.

특정한 ID와 PW를 API 서버에 signIn 으로 전달하게 된다면 API 서버에서는 해당 ID와 PW를 서버 내에 계정 정보와 비교하여 데이터에 틀린 게 없는 지 확인한다. 만약 문제가 생겼다면 에러를 전달하게 된다.
아이디와 비밀번호가 틀려서 HTTP Status 403 (Forbidden)을 Response Body에 담아 전달한다면, 클라이언트 사이드에서는 이 Response Body의 HTTP Status 값을 보고 '아이디와 비밀번호를 확인 해 주세요' 라는 경고창을 띄우게 된다.

만약 정상적으로 로그인이 되었다면 해당 유저에게 Authorization 이 부여되여 서비스를 사용할 수 있게 된다. Authorization은 유저마다 다르다. 관리자 유저라면 많은 권한들이 부여 된 상태로 서비스를 관리까지 할 수 있다면, 일반 유저라면 관리자 페이지 까지 접근은 힘들 것이다.

Session Based VS Token Based

여러가지 Authentication 방식들이 있지만 반드시 이해해야 하는 방식은 세가지가 있다.
Session, Token, 그리고 OAuth.

OAuth는 좀 다른 개념이라 Session 과 Token 방식만 비교하자면 다음과 같다.

Session Based Authentication 에서의 특징은 서버가 사용자들의 정보를 기억하고 있는다는 것이다.
사용자들의 정보들을 서버가 기억하려면 메모리를 활용하거나 DB를 사용해야 한다. 사용자가 로그인을 하게 되면 세션이 생성되고 세션에 사용자 정보를 저장해 둔 후 서비스를 제공할 때 해당 정보들을 활용한다. 물론 서버 내의 데이터 처리만 가지곤 한계는 존재한다. 그러므로 Cookie를 활용한다.

Cookie란 서버가 사용자의 웹 브라우저에 전달하는 데이터 조각이다. 이 데이터조각들은 동일한 서버에 또 다른 요청을 보낼 시 전달되는 데이터에 활용된다. 이를 통해 서버는 같은 브라우저에서 요청이 들어왔는지를 확인할 수 있다. 이렇게 하는 이유는 HTTP는 Stateless 하기 때문이다. 한번 Request에 대한 Response를 제공하고 나면 그 이후는 신경쓰지 않는다. 그러한 Request를 처리했단 사실 조차 기억하지 않는다. 그러므로 브라우저가 '나 아까 그놈이야!' 라고 주장 해 주어야 한다.

Sesseion Based Authentication은 여전히 쓰인다. 규모가 작은 시스템이라면 이런 방식이 오히려 나을 수도 있다. 하지만 문제점이 있다.

  1. 세션 데이터가 늘어난다면 서버에 무리를 줄 수 있다.
    • 계속해서 서비스 사용자가 늘어난다면 세션은 계속해서 늘어난다. 물론 세션은 어느정도 이상 사용하지 않는다면 정리될 수 있겠지만 동시 접속자가 갑자기 늘어난다면?
  2. 확장성
    • 사용자가 늘어난 만큼 트래픽을 처리하기 위한 다양한 기법들을 활용해야 하는데 세션은 엄연히 데이터이므로 이러한 데이터를 분산처리하는 방법들은 절대 쉬운 방법들이 아니다.
  3. CORS
    • Cookie는 단일 도메인 및 서브 도메인에만 작동하도록 설계 되어있다. 만약에 도메인이 여러개가 생긴다면 상당히 까다로운 문제가 될 수 있다.

Token based Authenticatoin은 서버가 유저에게 토큰을 보내는 방식이다. 인증을 받은 사용자들에게 토큰을 발행하고 서버에 Request를 보낼 때 토큰을 함께 보내도록 한다. 서버 입장에서는 더이상 사용자들을 위한 세션 정보들을 어딘가에 저장 할 필요가 없다. 또한 상태를 유지하지 않기 때문에 Stateless 한 구조를 가진다. 주로 JWT (JSON Web Token) 방식을 사용한다.

이런 방식은 쿠키를 따로 전달하지 않기 때문에 쿠키 사용에 대한 보안 취악점을 줄여준다. 또한 확장성에 제약이 되는 사항들이 많이 줄어들게 된다. 또한 여러가지 도메인들을 사용할 수 있게 된다. CORS 문제에서 자유로워 진다.

하지만 중간에 토큰을 탈취당하면 보안에 심각한 문제가 생긴다. 그러므로 토큰의 사용기간을 제한하는 방식으로 대처한다. 또한 토큰 데이터는 Request 데이터에 포함되어 전달되는데 토큰 그 자체의 용량이 크기 때문에 트래픽이 몰리면 부하가 심해질 수 있다.

JWT 즉 JSON Web Token에 대해 좀 더 설명하자면, Header, Payload, Signature 세 가지 데이터를 각각 Base64로 인코딩하여 전달하는 데이터이다.

https://jwt.io/

위의 사이트에 접속하면 실제로 JWT가 어떤 형태인 지 확인할 수 있다.

이미지에서도 볼 수 있다시피 각각의 영역은 점으로 구별 된다. Header에는 Signature 에 어떤 암호화 알고리즘이 사용되었는 지 등의 데이터가 저장 되어있다. Payload는 토큰 내에 첨부되는 실질적인 데이터들이 첨부 되어있다. 로그인 한 사람의 ID 등의 정보등리 포함 되어있다. Signature는 이 데이터가 인증 된 데이터라는 것을 증명하는 데이터들이 저장 되어있다. 비밀 키를 포함하여 정보들은 암호화 되어있다.

이런 JWT 토큰을 쓴다고 모든 문제가 해결되는 것은 아니다. JWT 토큰 내에 정보들이 들어가있으므로 토큰의 용량 자체가 커질 수 있고 토큰 자체는 Base64로 인코딩 되어있는 것이다보니 내용은 누구나 확인할 수 있다. 또한 Stateless 하기 때문에 토큰 자체의 만료시간이 필요하고 클라이언트 측에서 토큰을 저장하고 있어야 하는 문제가 있다.

OAuth


어떤 서비스를 사용하다보면 따로 회원가입을 하지 않더라도 네이버 아이디나 카카오 아이디 등 다양한 외부 서비스를 통해 로그인 할 수 있게 하는 기능들이 존재한다. 이와 같이 외부 서비스에서도 Authenticatoin을 가능하도록 하고 그 서비스의 API의 Authorization 을 제공하는 것을 OAuth라고 한다.

OAuth는 다수의 써드파티 프로그램에 개인정보를 제공하지 않고도 Authorization 을 제공 받도록 하려는 아이디어에서 출발 하였다. 자신의 개인정보가 여러가지 서비스에 모두 분산되어 제공되어있다면, 여러모로 골치아픈 일이 생길 수 있다. 특히 비밀번호가 탈취 당했을 때 모든 사이트들의 비밀번호를 변경해야 하는가?

OAuth는 생각보다 오래 된 기술은 아니다. OAuth 1.0은 트위터에서 먼저 제공하기 시작했다. 하지만 여러가지 기술적인 제약 때문에 한계가 있었다. 2010년 부터 OAuth 1.0 기술이 존재하긴 했지만, 웹이 아닌 다른 애플리케이션에서의 지원이 많이 부족했고 HMAC을 통해 암호화를 해야 했다. 인증 토큰이 만료되지 않는 문제점 또한 있었다.

OAuth 2.0 부터는 암호화를 HTTPS 에 맡겨버린다. 또한 API 서버에서 인증 서버를 분리할 수 있도록 설계하였다.

OAuth에 사용되는 용어들은 다음과 같다.

이름설명
사용자(User)서비스 제공자와 소비자를 사용하는 계정을 가지고 있는 개인
소비자(Consumer)Open API를 이용하여 개발된 OAuth를 사용하여 서비스 제공자에게 접근하는 웹사이트 또는 애플리케이션
서비스 제공자(Service Provider)OAuth를 통해 접근을 지원하는 웹 애플리케이션(Open API를 제공하는 서비스)
소비자 비밀번호(Consumer Secret)서비스 제공자에서 소비자가 자신임을 인증하기 위한 키
요청 토큰(Request Token)소비자가 사용자에게 접근권한을 인증받기 위해 필요한 정보가 담겨있으며 후에 접근 토큰으로 변환된다.
접근 토큰(Access Token)인증 후에 사용자가 서비스 제공자가 아닌 소비자를 통해서 보호된 자원에 접근하기 위한 키를 포함한 값.

인증 과정은 다음과 같다.

  1. 소비자가 서비스제공자에게 Request Token을 요청한다.
  2. 서비스제공자가 소비자에게 Request Token을 발급해준다.
  3. 소비자가 사용자를 서비스제공자로 이동시킨다. 여기서 사용자 인증이 수행된다.
  4. 서비스제공자가 사용자를 소비자로 이동시킨다.
  5. 소비자가 Access Token을 요청한다.
  6. 서비스제공자가 Access Token을 발급한다.
  7. 발급된 Access Token을 이용하여 소비자에서 사용자 정보에 접근한다.

그림으로 표현하면 다음과 같다. 페이코 개발자센터 Docs를 Reference 했다.

이렇게 생성 된 토큰은 서비스에서 자체적으로 관리해야 한다. OAuth 1.0 과는 다르게 Access Token 의 Life Time 을 지정함으로써 토큰 관리 또한 편하도록 변화하였다. OAuth 2.0은 처음부터 확장성과 표준화를 목적으로 개발 되어있기 때문이다.

Outro

Authentication 에 대한 개념, 세 가지 Authentication 방법에 대해 알아보았다.
다음 포스팅 할 시리즈의 주제는 Cashing이다. 갈 수록 내용이 어려워지는 감이 있지만....로드맵의 마지막까지 완주 해 보도록 하자.

Reference

https://www.geeksforgeeks.org/session-vs-token-based-authentication/
https://developer.mozilla.org/ko/docs/Web/HTTP/Cookies
https://ko.wikipedia.org/wiki/JSON_%EC%9B%B9_%ED%86%A0%ED%81%B0
https://ko.wikipedia.org/wiki/OAuth
https://developers.payco.com/guide/development/start
https://d2.naver.com/helloworld/24942

profile
블로그 이전합니다 : https://swj-techblog.vercel.app/

0개의 댓글