세션 인증 방식 VS Token 인증방식

Park sang woo·2024년 7월 17일
6

CS스터디

목록 보기
5/25

🐬 인증과 인가

HTTP는 본래 정보를 유지하지 않는 statless한 특성을 가져, 각 특성의 상태가 유지되지 않기 때문에 웹사이트에서 인증을 관리하기 위한 방법이 필요합니다.



인증은 유저가 누구인지 확인하는 절차입니다.

인가는 인증을 통해 검증된 사용자가 애플리케이션 내부의 리소스에 접근할 때 사용자가 해당 리소스에 접근할 권리가 있는지를 확인하는 과정.
로그인을 했는데 게시판 접근 등급으로 인해 접근이 허가되거나 거부되는 것.

  • ex) 댓글 달기, 내가 작성한 글 수정

리소스 : 사용자가 애플리케이션에 접근하여 수행하려는 모든 작업과 접근하려는 데이터가 리소스에 해당.


📧 어떤 사이트나 서비스에서 인증과 인가를 하기 위해서 사용자의 로그인 상태를 서버가 인지할 수 있도록 하는 방법은 어떤 것이 있을까??


서버는 웹사이트에서 무수한 사용자들의 요청에 응답해줍니다. 로그인을 하고 이용하는 사용자와 하지 않고 이용하는 사용자가 있을 때 서버는 사용자의 요청마다 인가를 해줄지 말지 결정해서 응답을 해줘야 합니다.
사용자가 로그인을 하면 서버는 세션을 출력해줍니다.


🐬 Session 기반 인증 방식

session
일정 시간 동안 같은 사용자(정확히는 브라우저)로부터 들어오는 일련의 요구를 하나의 상태로 보고 그 상태를 일정하게 유지시키는 기술입니다.

cookie
특정 웹 사이트를 방문했을 때 만들어지는 정보를 담는 파일을 지칭하는 것입니다.
상태 정보를 유지하는 기술.


📜 동작 방식

  • 세션 식별키로 SessionId를 기준으로 정보를 저장합니다.
  • 서버에서 sessionId를 cookie에 담아 브라우저로 전달한다.
  • 브라우저는 모든 request에 cookie(sessionId)를 함께 전송합니다.
  • 서버는 브라우저가 보낸 sessionId를 키로 서버 메모리에서 사용자의 session 정보를 식별하고 유효하다면, 원하는 응답을 제공해줍니다.


📜 장단점

+ 서버에서 클라이언트의 상태를 유지하므로 사용자의 로그인 여부 확인이 용이하고, 경우에 따라서 강제 로그아웃 등의 제재를 가할 수 있습니다.

  • 서버 관리자는 해당 세션의 권한을 가지는데 보안 팀이 사용자의 계정이 손상된 것을 의심하게 된 경우 세션 ID를 즉시 비활성화하여 사용자가 즉시 로그아웃되도록 할 수 있습니다.

+ 구현이 명확하여 실제 서버에서 로그인 상태가 굉장히 유용합니다.

  • 서버는 세션 ID를 통해 인증을 관리하므로, 복잡한 토큰 검증 로직을 구현할 필요가 없습니다. 세션 ID가 유효한지만 확인하면 되므로, 서버 로직이 단순해집니다.
  • 특히 서버가 여러 대일 때 세션 스토어(예: Redis)를 사용하여 중앙에서 세션을 관리함으로써 더욱 효율적으로 구현할 수 있습니다.

+ 클라이언트가 임의로 정보를 변경시키더라도 서버에서 클라이언트의 상태 정보를 가지고 있으므로 상대적으로 안전합니다.

+ 서버에서 클라이언트의 상태를 모두 유지하고 있어야 하므로 메모리, 디스크 또는 DB에 부하가 심합니다.

+ 사용자가 많아지는 경우 로드 밸런싱을 사용한 서버 확장을 이용해야 하는 데 이 때 세션의 관리가 어려워집니다.

+ 웹 브라우저에서 세션 관리에 사용하는 쿠키는 단일 도메인 및 서브 도메인에서만 작동하도록 설계되어 CORS 방식(여러 도메인에 request를 보내는 브라우저)을 사용할 때 쿠키 및 세션 관리가 어렵다.

+ 멀티 디바이스 환경(모바일, 공동 사용 등)에서 로그인 시 중복 로그인 처리가 되지 않는 등의 신경 써야 할 부분들이 발생합니다.






🐬 토큰 기반 인증 방식(JWT)

인증받은 사용자들에게 토큰을 발급하고, 서버에 요청을 할 때 헤더에 토큰을 함께 보내도록 하여 유효성 검사를 한다.
이러한 시스템에서는 더이상 사용자의 인증 정보를 서버나 세션에 유지하지 않고 클라이언트 측에서 들어오는 요청만으로 작업을 처리한다.
즉, 서버 기반의 인증 시스템과 달리 상태를 유지하지 않으므로 Stateless한 구조를 갖는다.

Session 기반 인증 방식과 가장 큰 차이점은 유저의 정보가 서버에 저장되지 않고 서버는 유저 인증을 위해 많은 일들을 하지 않아도 됩니다.

JWT는 JSON Web Token의 약자로 전자 서명된 URL-Safe(URL로 이용할 수 있는 문자만 구성된)의 JSON입니다.
전자 서명은 JSON의 변조를 체크할 수 있게 되어 있습니다.
JWT는 속성 정보(Claim)를 JSON 데이터 구조로 표현한 토큰으로 RSA를 이용한 Public Key/Private Key 쌍으로 서명할 수 있습니다.
JWT는 서버와 클라이언트 간 정보를 주고받을 때 HTTP Requset Header에 JSON 토큰(Access Token)을 넣은 후 서버는 별도의 인증 과정 없이 헤더에 포함되어 있는 JWT 정보를 통해 인증합니다.


📜 토큰 구성요소

  • Header: 어떤 알고리즘으로 암호화 할 것인지, 토큰은 어떤 타입을 쓸 것인지 같은 토큰 관련 정보가 담겨있습니다.
    alg는 HMAC, SHA256 또는 RSA같은 해시 알고리즘을 나타내고 typ 는 토큰 유형(JWT)을 나타냅니다.

  • Payload: 사용자 인증 관련 정보가 담긴다. 수정이 가능하여 더 많은 정보를 추가해둘 수도 있다. 그러나 이 곳은 노출과 수정이 가능한 지점이기에 인증이 필요한 최소한의 정보만 담아야한다! 인증에 필요한 최소한의 정보란 아이디, 비밀번호, 개인정보 등이 아니라 이 토큰을 가졌을 때 권한의 범위, 토큰의 발급일과 만료일자 등을 의미한다.

  • Signature: 가장 중요한 역할.
    부호화시킨 Header와 Payload를 가지고 발급해준 서버가 지정한 secret key로 암호화시킵니다. 이렇게 하면 토큰을 변조하기 어려워집니다.

구체적 사례
토큰 발급된 이후에 누군가 Payload 정보를 수정합니다.
Payload는 조작된 정보가 들어가 있지만 Signature에는 변경되기 전 Payload 내용을 기반으로 암호화된 결과가 저장되어 있습니다. 조작 후 Payload를 암호화한 결과와는 다른 값이 나옵니다. 이러면 토큰 조작 여부를 쉽게 알 수 있습니다. -> 조작된 토큰을 악용하기 어렵습니다.

JWT는 접근 권한 유무를 DB에 저장하지 않습니다. JSON 파일에 저장해두되 암호화 알고리즘에 의존해서 토큰 변조여부를 확인합니다.



📜 Access Token과 Refresh Token

두 키 모두 사용자가 로그인하고 인증됐을 경우 서버에서 Secret Key를 사용해서 발급하는 토큰입니다.

Access token은 글자 그대로 사용자가 서버에 request를 보낼 때 header에 함께 보내는 접근용 토큰으로 만료 기간을 10~15분으로 짧게 두어 자주 발급받게 합니다. -> 안전성 유지

Refresh token은 access token이 만료됐을 때, access token을 재발급받기 위한 인증용 토큰입니다. 평소의 요청에는 request에 포함되지 않으면 오직 access token을 재발급받는 용도로만 사용합니다.
만료 기간은 자동 로그인 기능을 몇 달로 지정할 것인가에 따라 조절하면 되고, 만료 기간이 끝나면 사용자에게 로그인을 다시 요청하면 된다.



📜 동작 방식

  • 로그인 요청 시 서버에서 Secret Key를 사용해서 JWT를 발급합니다.
  • JWT가 브라우저로 전달되면 사용자의 Local Storage에 JWT를 저장합니다.
  • 브라우저는 모든 요청의 헤더에 Access Token을 함께 전송합니다.
  • 서버는 브라우저가 보낸 Access Token을 식별하고 유효하다면 원하는 응답을 제공해줍니다.

특징

  • 서버가 클라이언트의 정보를 저장하지 않으므로 Statless한 서버입니다.
  • 클라이언트는 JWT를 Local Storage에 저장합니다.
  • JWT 발급과 매 요청마다 Header에 넘어오는 Access Token의 유효성 검사만 진행합니다.


📜 장단점

+ JWT를 클라이언트에서 저장하므로 서버의 메모리, DB 등의 부담이 없습니다.
+ 로드 밸런싱을 사용한 서버 확장이 용이합니다.
+ 멀티 디바이스 환경에서 부단이 없습니다.
+ access token의 만료 기간이 짧아 타인에게 도난당하더라도 안정성이 높습니다.
+ CORS 방식을 사용하기 용이합니다.

+ 서버에서 클라이언트의 상태를 저장하고 있지 않으므로, 사용자의 로그인 여부 확인, 경우에 따른 강제 로그아웃 등의 제재를 가하는 데 어려움이 있습니다.

+ 클라이언트가 임의로 토큰을 수정하거나 구조가 변경되게 되면 서버에서 확인할 수 없어 세션 방식에 비해 상대적으로 안정성이 낮습니다.

+ Refresh Token이 도난됐을 경우 계속해서 Access Token을 발급받으며 악용될 가능성이 있습니다. -> 만료 기간을 짧게 설정.

+ 일반적으로 Payload 부분에 사용자의 필요한 모든 정보를 저장하는 경우가 많아 SessionId의 길이보다 깁니다. (즉, HTTP request가 무거워질 수 있다.)

+ XSS 공격에 취약할 수 있어 민감한 정보를 포함하는 경우 위험할 가능성도 있습니다



🐬 HTTP & HTTPS

🖇️ https://velog.io/@winsome_joo/HTTP-HTTPS



🐬 OSI 7계층

🖇️ https://velog.io/@luda412/OSI-7-Layer



🐬 TCP/IP

🖇️ https://velog.io/@wjd15sheep/TCPIP-UDP



Reference

🖇️ https://jwt.io/introduction
🖇️ https://simgee.tistory.com/35
🖇️ Session/Token 인증 방식
🖇️ JWT 기반 인증 방식

profile
일상의 인연에 감사하라. 기적은 의외로 가까운 곳에 있을지도 모른다.

0개의 댓글