[인증/인가] 쿠키, 세션, 토큰(JWT)

동동주·2024년 5월 9일
0

초록 스터디

목록 보기
2/4

1. 인증과 인가

로그인 기능 구현은 크게 두 가지 부분으로 나뉠 수 있다. 바로 인증과 인가이다.

💡인증(Authentication)

  • 인증은 우리가 보통 하는 로그인이라고 생각하면 된다.
  • 어떤 사이트에 가입된 회원, 즉 특정 서비스에 일정 권한이 주어진 사용자임을 아이디와 패스워드를 통해 확인 받는 과정이다.

💡인가(Authorization)

  • 인가는 이렇게 한 번 인증을 받은 사용자가 이후 사이트의 여러 기능들을 사용할 때 서버가 해당 사용자가 로그인 되어있음을 알아보고 허가해주는 것을 말한다.

인스타그램을 예시로 들자면,
인스타그램에 로그인하는 것이 '인증'하는 것이고
로그인된 계정으로 친구들의 스토리를 보고 피드를 보거나 댓글을 다는 등 해당 사용자 계정으로'만' 할 수 있는 활동을 시도할 때 서버에서 로그인되어있음을 알아보고 허가해주는 것이 '인가'이다.

2. 쿠키 방식

쿠키 인증 방식은 쿠키에 사용자의 인증 정보를 담아서 인증하는 방식이다.

  • 클라이언트가 인증 정보를 관리하기 때문에 stateless하다.

❓ stateless와 stateful
stateless는 무상태로, 클라이언트-서버 관계에서 서버가 클라이언트의 상태를 보존하지 않음을 의미한다.
- Stateless 구조에서 server는 단순히 요청이 오면 응답을 보내는 역할만 수행하며, 세션 관리는 클라이언트에게 책임이 있다.
- 따라서 Stateless 구조는 클라이언트와의 세션 정보를 기억할 필요가 없으므로, 이러한 정보를 서버에 저장하지 않는다. 대신 필요에 따라 외부 DB에 저장하여 관리할 수 있다.
stateful 은 상태유지로, 클라이언트-서버 관계에서 서버가 클라이언트의 상태를 보존함을 의미한다.
- 클라이언트의 이전 요청이 서버에 잘 전달되었을 때, 클라이언트의 다음 요청이 이전 요청과 관계가 이어지는 것을 의미한다.

  • 인증/인가 flow는 다음과 같다.

    1) 클라이언트가 서버에 첫 로그인 인증 요청을 보내면, 서버에서 응답으로 쿠키에 사용자 인증 정보를 담아서 보낸다.
    2) 서버에서 응답한 쿠키를 클라이언트에서 저장하고, 인증/인가 요청 시마다 서버로 요청한다.

👍장점:

  • 사용자의 인증 정보를 클라이언트가 관리하기 때문에 서버 부하가 적다.
  • 인증 상태를 서버가 관리하지 않고 매번 클라이언트의 인증 정보를 담은 쿠키의 요청을 받을 때 처리하므로 Stateless하다.

👎단점:

  • 클라이언트(사용자)가 쉽게 쿠키에 담긴 인증 정보를 위조할 수 있다.
  • 쿠키의 데이터 크기가 제한적이고, 또 크기가 커진다면 네트워크 부하가 심해진다.

2. 세션 인증 방식

세션 인증 방식은 세션으로 사용자의 인증 정보를 관리하는 방식이다.

  • 서버가 인증 정보를 관리하기 때문에 stateful하다.
  • 인증/인가 flow는 다음과 같다.

    1) 클라이언트가 서버에 첫 로그인 인증 요청을 보내면, 서버에서 인증 정보를 저장하고 SessionID를 클라언트에게 제공
    2) 서버에서 받은 SessionID로 서버에게 인증/인가 요청을 하여 서버에서 SessionID에 해당하는 인증 정보로 인증/인가 처리
  • flow에도 나와있듯이, 세션 인증 방식은 사용자의 인증 정보를 클라이언트가 아닌 서버가 관리하게 된다.

👍장점:
1) 한 사용자의 디바이스별 인증을 관리할 수 있다.

  • PC로 접속 시 다른 기기(모바일, 태블릿 등)의 접근을 막을 수 있다.
  • 여러 디바이스에서 접속 중일 때 특정 디바이스의 유저를 로그아웃하게 할 수 있다. (인스타그램)

2) 하나의 계정 공유를 관리할 수 있다.

  • 넷플릭스처럼 계정 공유의 수도 제한할 수 있다.

3) 비정상적인 접근 신고가 들어오면, 서버에서 판단하여 해당 세션을 삭제해서 바로 로그아웃시킬 수 있다.

❓서버 내부 어디에서 사용자 인증 정보 관리하나요?

사용자 인증 정보를 관리하는 곳은 크게 메모리, 하드 디스크, DB 이렇게 3가지이다.
1. 메모리 영역/하드디스크

  • 먼저 메모리 영역에서 사용자 인증 정보를 관리하게 되면, 뒤에 나올 나머지 2가지 방식보다 속도가 빠르다.
    - 하지만, 단점으로 사용자가 동시에 SessionId로 인증 요청을 많이 보내게 되면 서버 메모리가 부족해지고, 서버를 껐다 켰을 때 Session 정보가 휘발된다는 치명적인 단점이 존재한다.
  • 두번째로 하드디스크에서 관리하게 되면 메모리 영역보다 속도는 느리지만 DB보다는 속도가 빠르다.
  1. 서버 DB
  • 속도가 위의 2가지 방법보다 느리지만, 위에서 말한 단점들을 모두 해결할 수 있다.
  • 그래서 인증/인가 방식으로 세션을 이용한다면 보통은 서버 DB로 사용자 인증 정보를 관리한다!
  • 하지만 로그인한 모든 유저의 인증 정보를 DB에 관리해야하므로 무겁고, 매 인증마다 DB를 거쳐 인증 정보를 Select 해야하므로 연결 비용이 크다는 단점이 존재한다. 서버 부하도 상대적으로 클 수 있다는 단점이 있다.

3. JWT 토큰 방식

토큰의 방식 중 JWT 토큰이 가장 간단하고 대표적이다.

  • 클라이언트가 인증 정보를 관리하기 때문에 stateless하다.

  • 인증/인가 flow는 다음과 같다.

1) 클라이언트가 서버에 첫 로그인 인증 요청을 보내면, 서버에서 응답으로 Token을 담아서 보낸다.
2) 서버에서 응답한 Token을 클라이언트에서 저장하고, 인증/인가 요청 시마다 서버로 요청한다.

  • 기본적으로는 클라이언트가 인증 정보를 관리하기 때문에 쿠키 인증 방식과 Flow가 비슷하다.
  • 차이가 있는 부분은, 쿠키가 아닌 JWT 토큰을 매개체로 인증한다는 것과 서버에서 '토큰 검증'이 이루어진다는 점이다.
  • 이를 통해 쿠키보다는 보안적으로 안전하게 관리될 수 있다.

👉 JWT를 간단하게 설명하면, 사용자의 인증 정보와 서버의 SecretKey로 서버가 생성한 Token이다.

  • 여기서 중요한 점은 '서버의 SecretKey로 서버가 생성한 Token'이라는 점이다!
  • 클라이언트가 Token을 저장하고 인가 요청 시에 발급받은 Token을 사용하여 요청을 보내기 때문에 Token을 클라이언트가 관리한다는 점은 쿠키 인증 방식과 비슷하지만, 서버에서도 해당 Token에 대한 SecretKey를 가지고 있다는 점에서 쿠키 인증 방식과 다르다.
  • 앞에서 말한 '토큰 검증'이라는 것이 바로 요청으로 온 Token이 서버에서 발급한 Token인지 검증하는 단계이다. 이때, 요청으로 온 Token의 SecretKey가 다르다면 위조, 변조된 Token이라고 판단하여 인증 에러를 발생시키게 된다.

이러한 검증 단계를 거치기 때문에 쿠키 인증 방식보다는 보안상 훨씬 안전하다.

  • 추가로, 세션 방식과 비교해서는 기본적으로 클라이언트가 Token을 관리하기 때문에 서버 부하가 비교적 덜하다는 장점이 있다.

  • 하지만, Token을 검증하는 것뿐이지 해당 Token을 관리하는 것이 아니기 때문에 세션보다 보안상 취약하고 비정상적인 유저라고 판단 시 Token을 만료하거나, 디바이스별 제어 등 세션에서 가능했던 부분들이 불가능하다.

  • 위에서 설명한 Token은 모두 AccessToken을 의미하고 물론 RefreshToken을 사용하면 가능해지긴 하지만 세션 방식에 비해서는 완벽하지 못하다.


토큰 인증/인가 방식을 요약해보자면,

  • 클라이언트가 인증 정보를 관리한다는 점에서는 쿠키 인증 방식과 비슷하지만, 쿠키 대신 JWT 토큰을 사용하고, 서버에서 해당 토큰을 검증하는 단계를 거쳐 보안상 쿠키 방식보다 뛰어나고, 서버 부하가 비교적 덜 하다는 장점이 있었다.
  • 하지만, 보안이 세션 방식 보다는 취약하고 세션 방식의 여러 기능들을 사용할 수 없다는 단점이 존재했다.

🔖 출처:

0개의 댓글