사용자 인증(Auth)의 기본

정균·2022년 6월 29일
1
post-thumbnail

클라이언트에서 인증이 필요한 이유

하나의 웹사이트에는 수많은 사용자들이 있다. 각 사용자들은 원하는 데이터도 다르고 가지고 있는 컨텐츠도 모두 다르다. 서버는 사용자의 요청에 맞춰 데이터를 전송해야 하는데, 이 때 서버는 요청을 보낸 사용자가 누군지 정확하게 알 필요가 있다. 사용자가 누군지 확인을 정확히 하지 않는다면 나의 정보는 타인에게 유출될 것이다. 그러므로 클라이언트에서 요청을 보낼 때, 자신이 누구인지 알만한 단서를 서버에게 보내줘야 한다.

마치 배민에서 포장 주문을 하고 식당을 찾아갔는데 본인을 증명할 수단(주문 번호, 배민 닉네임 등)이 없다면 어떻게 될까? 식당 주인은 이 사람이 주문한 사람이 맞는지 확신하지 못하므로 음식을 선뜻 주지 못할 것이다. 이를 해결하기 위해선 본인을 증명할 수단이 필요하다.

HTTP

현재 웹에서 가장 많이 쓰이는 통신 방식은 http 요청 방식이다. http 요청 데이터는 크게 헤더와 바디로 구성되어 있다. 헤더에는 요청에 대한 정보를 포함하고, 바디에는 요청 내용이 포함된다. 일반적으로 인증 정보는 헤더에 넣어 요청을 보내게 된다

다시 포장 주문을 예시로 들면 헤더는 주문 번호를 포함하고, 바디는 무엇을 주문했는지를 포함한다.

사용자 인증의 방식

  1. 세션/쿠키 방식
  2. 토큰 기반 인증 방식(JWT)

사용자 인증 방식에는 위와 같이 크게 두 가지 방식이 있다.
토큰 방식에서 더 나아가서 OAuth와 같은 방식이 있다.

근데.. 아이디 패스워드만 입력하면 되는거 아닌가?

분명 로그인 할 때 아이디와 패스워드를 통해 인증을 했는데 세션이나 토큰같은건 왜 사용할까? 그 이유는 브라우저에 로그인 정보를 저장하고 유지시키기 위해서 사용한다. 서버로 새로운 데이터를 요청할 때마다 아이디와 패스워드를 입력하면 매우 불편할 것이다. 이 불편함을 없애기 위해 처음에만 아이디 패스워드를 입력하고 세션이나 토큰을 발급받아 브라우저에 저장을 해서 일정 기간 동안 유지시킨다. 이 인증 정보는 서버로 요청을 할 때마다 사용한다.

세션/쿠키 방식

초기에는 계정 정보(아이디, 패스워드 등)를 요청 데이터에 포함해서 보냈다.
이 방식은 보안에 매우 취약했고, 이를 보안하기 위해 새롭게 등장한 것이 세션/쿠키 방식이다.
세션/쿠키 방식의 순서는 다음과 같다.

  1. 사용자가 로그인한다.
  2. 서버에서는 회원 DB에서 로그인 정보(id, password 등)를 확인하고 고유 세션 ID를 만들어서 사용자에게 전송한다.
  3. 사용자는 받은 세션 ID를 쿠키에 저장하고 서버 요청 시 인증이 필요할 때마다 쿠키를 헤더에 실어 보낸다.
  4. 서버에서는 받은 요청에서 쿠키를 세션 저장소에서 대조 한 후 해당 세션에 맞는 정보를 사용자에게 보낸다.

장점

  1. 세션/쿠키 방식은 쿠키를 사용해서 인증한다. 쿠키에는 세션 저장소에 담긴 정보를 얻기 위한 id 값만 갖고 있기 때문에 이를 탈취해도 큰 의미는 없다. 중요한 유저 정보는 세션 저장소에 저장되어 있다.
  2. 세션/쿠키 방식은 구현이 명확하다.

단점

  1. 해커가 쿠키 자체를 탈취했다면 그 쿠키를 넣어서 서버에 요청을 하면 서버는 해당 요청이 해커가 보낸건지, 인증된 사용자인지 구별할 수 없다.
    -> https를 사용하면 극복할 수 있다.
  2. 서버에서 사용자별 세션을 저장할 세션 저장소가 따로 필요하다. 이에 따른 추가적인 저장공간이 필요하고 서버에 걸리는 부하도 높아진다.

토큰 기반 방식(JWT)

JWT 방식은 Json Web Token의 약자로 인증에 필요한 정보들을 암호화시킨 토큰을 뜻한다.
클라이언트는 토큰을 HTTP 헤더에 실어서 서버 요청을 하게 된다.
세션/쿠키 방식은 사용자별 세션ID를 서버의 저장소에 저장하는 반면, 토큰 방식은 토큰 자체에 인증에 필요한 정보들을 암호화 시켜서 저장한다.

쉽게 얘기해서 어떤 기관에서 행사를 한다고 했을 때,
세션/쿠키 기반 방식은 기관에서 이용객들의 정보를 담은 장부를 통해 관리하는 느낌이고,
토큰 기반 방식은 이용객들에게 티켓을 나눠줘서 이용하게끔 관리하는 느낌이다.
비유가 맞는진 모르겠다..

토큰 기반 방식의 순서는 다음과 같다.

  1. 사용자가 로그인한다.
  2. 서버는 로그인 정보(id, password 등)을 확인하고 클라이언트에게 토큰을 발급한다.
  3. 클라이언트는 토큰을 받아서 저장하고 인증이 필요한 서버 요청시 토큰을 헤더에 실어 보낸다.
  4. 서버는 받은 요청에서 토큰이 유효한지 확인하고 해당 정보를 클라이언트에게 보낸다.

장점

  1. 유저 정보를 서버가 아닌 클라이언트에 저장하므로 서버 부담이 적다.
  2. 확장성이 뛰어나다. 토큰 기반의 다른 인증 시스템에서도 접근이 가능하다. 예를 들어 페이스북, 구글, 네이버 로그인 등은 모두 토큰을 기반으로 인증한다.

단점

  1. 이미 발급된 토큰의 경우 유효기간이 끝날 때까지 돌이킬 수 없다. 세션/쿠키 방식의 경우 쿠키가 탈취되었다는 점을 알게 되면 해당 세션을 세션저장소에서 지워버리면 된다. 그러나 토큰의 경우 해커한테 탈취되어도 유효기간이 끝날 때까지 서버에서 어찌할 도리가 없다.
    -> Refresh 토큰 도입으로 극복할 수 있다.
  2. JWT의 데이터 길이는 세션/쿠키 방식의 길이보다 훨씬 길다. 그러므로 인증이 필요한 요청이 많을수록 자원낭비가 발생한다.

Refresh 토큰

토큰 방식의 경우 해커한테 토큰이 뚫릴 경우 유효기간이 끝날 때까지 막을 수 없다는 단점이 있었다. 이를 막기 위해 유효기간을 짧게 설정한다면 사용자는 로그인을 자주해야 하므로 불편함을 초래한다.

이를 막기 위해 Refresh 토큰 방식을 도입했다. 이 방식은 Access 토큰의 유효기간은 짧게 설정하고, Refresh 토큰의 유효기간은 길게 설정한다. 클라이언트는 길게 설정된 Refresh 토큰의 경우 더 안전한 저장소에 저장하고, Access 토큰을 헤더에 실어 서버에 요청한다. Access 토큰이 만료되었을 경우 Refresh 토큰을 사용해 새로 발급받는다.

이 방식을 사용하면 Access 토큰이 탈취 당해도 짧은 유효기간 때문에 더 안전하고, 로그인 빈도도는 더 적게 할 수 있어서 보안과 사용자 편의 둘 다 모두 챙길 수 있다.

profile
💻✏️🌱

0개의 댓글