React

React : 인증 / 인가 - 쿠키, 세션, 토큰, JWT

고래고래00 2024. 6. 11. 15:21

인증(authentication)과 인가(authorization)

인증, 인가의 개념

  • 인증(Authentication) : 서비스를 이용하려는 유저가 등록된 회원인지 확인하는 절차 (로그인 과정)
  • 인가(Authorization) : 인증을 받은 유저가 특정 리소스에 접근할 수 있는 권한이 있는지 확인하는 절차 (로그인 이후)

HTTP 프로토콜의 특징 2가지

무상태(stateless)

각 요청이 독립적이며, 서버가 이전 요청에 대한 정보를 기억하지 않음

클라이언트서버에 요청을 보낼 때마다 서버는 해당 요청을 독립적으로 처리

이전 요청의 상태나 정보를 기억하지 않음

  • 상태값은 매 요청마다 클라이언트가 가지고 오기 때문에
    서버는 클라이언트의 상태를 별도로 기억할 필요없이 주문받은 대로 응답
  • 무상태라는 특성 덕분에 동일한 서버를 여러개로 확장 가능(Scale-Out)
더보기

무상태 ⇒ scale out

각 서버는 상태를 기억할 필요가 없기 때문에

동일한 애플리케이션을 여러 대의 서버에 배포하고

부하를 관리할 수 있는 로드 밸런서를 이용해 들어오는 요청을 여러 서버로 분산시킬 수 있다는 의미

 

이렇게 되면, 각 서버는 독립적으로 요청을 처리할 수 있기 때문에, 하나의 서버에 장애가 발생하더라도 다른 서버가 계속해서 요청을 처리할 수 있어 안전

비연결성(connectionless)

서버와 클라이언트는 연결되어 있지 않음 => 서버 입장에서는 매번 새로운 요청

  • 비연결성으로 인해 최소한의 서버 자원으로 서버를 유지할 수 있음
  • 그러나, 각 사용자별 요청이 잦은 서비스의 경우 이러한 비연결성은 오히려 비효율적

 

쿠키, 세션, 토큰

쿠키

쿠키란 브라우저에 저장되는 작은 데이터 조각이며, key-value 형태로 저장

  • HTTP의 무상태성과 비연결성 특성을 가져도 쿠키를 사용하여
    마치 서버가 클라이언트의 인증 상태를 기억하는 것처럼 구현
  • 쿠키는 별도로 삭제 처리하거나 유효기간이 만료되지 않는 한, 서버와 통신할 때 자동으로 주고받음
  • 서버에 특정 API 요청을 했을 때(ex : 로그인 요청) 서버가 응답 시 헤더에 Set-Cookie 속성으로 쿠키 정보를 담아주면, 응답을 받은 브라우저는 쿠키를 브라우저에 자동으로 저장
  • 서버에 http 요청 할 때 마다 브라우저에 저장되어 있는 쿠키는 자동으로 서버에 보내짐
  • 쿠키는 클라이언트에서 직접 추가/수정/삭제 가능

세션

  • 세션이란 사용자와 서버 간의 연결이 활성화된 상태를 의미하는 개념 (또는 인증이 유지되고 있는 상태)
  • 로그인 성공 → 서버에서 세션 생성 및 저장(key-value 형식) → key(sessionId)를 브라우저에 응답(by 쿠키)
더보기

서버는 이 세션 정보를 메모리, Redis(인메모리DB), DB 등 다양한 곳에 저장할 수 있음

서버에서 sessionId를 설정하고 브라우저로 보내면, 브라우저는 이를 쿠키에 저장

  • 세션 유지 상태 : 서버에서 관리하는 세션 저장소에 회원 데이터가 있음
  • 세션 만료 상태 : 서버에서 관리하는 세션 저장소에 회원 데이터가 없음
  • 서버는 인가가 필요한 API 요청을 받으면 클라이언트 쿠키에 들어 있는 sessionId를 세션 저장소에 조회하여
    있으면 DB에 데이터를 조회하여 응답

세션 인증 방식의 한계

  • 확장성 문제: 세션 정보는 서버의 메모리나 저장소에 저장되기 때문에, 서버가 많아질수록(예: 서버 확장(Scale-Out) 시) 세션 동기화 문제가 발생
    여러 서버가 동일한 세션 정보를 공유해야 하므로, 이를 관리하기 위한 추가적인 복잡성이 필요

  • 메모리 사용량 증가: 많은 사용자가 접속할 경우, 각 사용자의 세션 정보를 서버 메모리에 저장하는 방식은 메모리 사용량이 급증 => 서버 성능 저하와 비용 증가를 초래

  • 상태 유지의 복잡성: 세션은 서버에 상태를 저장하므로 서버가 무상태(stateless)로 유지되기 어려움
    RESTful 아키텍처의 원칙과 맞지 않음

  • 보안 문제: 세션 ID가 탈취될 경우, 이를 통해 사용자의 세션을 가로채는 세션 하이재킹(Session Hijacking) 공격이 발생할 수 있음

세션 인증 방식의 이러한 한계를 극복하기 위해 등장한 것이 바로 JWT(JSON Web Token)

JWT는 서버 확장성, 무상태성 유지, 보안성 등을 개선한 토큰 기반의 인증 방식

 

토큰

  • 클라이언트에서 보관하는 암호화 또는 인코딩된 인증 정보를 의미
    서버의 상태를 유지하지 않고도 클라이언트의 인증 상태를 확인
  • 세션처럼 서버에서 사용자의 인증 정보를 보관할 필요가 없기 때문에 서버 부담을 줄여주는 인증 수단
  • 웹에서 인증 수단으로 사용되는 토큰은 주로 JWT(Json Web Token)을 이용
더보기

암호화 / 인코딩 차이

  • 암호화는 데이터를 특정 알고리즘으로 변환하여 인가된 사용자만이 읽을 수 있도록 하는 과정이며, 기밀성을 유지
  • 인코딩은 데이터를 다른 형식으로 변환하여 전송 및 저장을 용이하게 하는 과정으로, 특별한 키 없이도 원래 형태로 복원할 수 있습니다.
  • 암호화는 보안 목적, 인코딩은 데이터 처리 목적입니다. 암호화된 데이터는 복호화 키가 필요하지만, 인코딩된 데이터는 키 없이도 복원 가능

JWT

JWT는 토큰 기반 인증 방식에서 사용되는 특별한 토큰, 로그인한 사용자가 이후에 서버에 요청을 보낼 때 사용

 

JWT의 세 가지 부분

  1. 헤더(Header): 어떤 종류의 토큰인지와 어떤 알고리즘으로 서명되었는지에 대한 정보
  2. 본문(Payload): 실제로 중요한 데이터가 들어있는 부분
                             예를 들어, 사용자 ID, 토큰의 만료 시간 등이 여기에 포함
  3. 서명(Signature): 이 부분은 토큰이 위조되지 않았는지 확인하는 역할
                                서버만이 알 수 있는 비밀 키로 서명 => 이 서명 때문에 토큰의 무결성이 보장
더보기
jwt.io에서 이런 내용을 테스트 가능 https://jwt.io/

JWT 특징

  1. 국제 인터넷 표준 인증 규격 중 하나
  2. 인코딩된 토큰을 누구나 복호화하여 payload를 볼 수 있음
    => 토큰의 용도는 인증정보(payload)에 대한 보호가 아니라 위조 방지
  3. 정보(payload)를 토큰화할 때 signature에 secret key가 필요하고, secret key는 복호화가 아니라 토큰이 유효한 지를 검증하는 데 사용

 

더보기

Refresh Token 으로 보안을 강화하는 것은 중요

 

리소스 접근 인가를 받기 위해 사용되는 토큰을 Access Token

Access Token의 만료기간을 길게 잡고 인증상태를 오래 가져갈 경우 서버 부담은 줄어드나 보안성(탈취 당할 경우)에 허점

인증 보안이 중요한 서비스의 경우 인증 시 2개의 토큰 (Access Token, Refresh Token)을 발급

Access Token의 기간은 30분 정도로 짧게 가져 가고, Refresh Token은 1~2주 정도로 길게 잡는 경우가 많습니다.

이 경우 서버에서는 Access Token이 만료되었을 때 Refresh Token 이 유효한 상태면 새로운 Access Token을 클라이언트에 발급해주고 인증상태를 유지할 수 있도록 하고, Refresh Token 만료 시 다시 로그인하라는 메시지를 응답합니다.