CS/네트워크

인증과 인가 ( 쿠키/세션/토큰/JWT)

Timha 2023. 1. 6. 13:43

세션 기반 인증과 토큰 기반 인증

세션과 토큰을 설명하기 전에!

  • 바로 직전의 통신도 기억 못하는 HTTP

HTTP는 stateless한 특성을 가지기 때문에 각 통신의 상태는 저장되지 않는다

하지만 우리가 웹 서비스를 사용할 때를 생각해봅시다.

매번 새 페이지를 요청 할 때마다 로그인을 해야 한다면 사용이 불가능할 것입니다.

이를 보완하기 위해 세션과 토큰을 사용!

유저가 로그인을 시도할 때 서버상에서 일치하는 유저 정보를 찾았다면

인증(Authentication) 확인의 표시로 세션이나 토큰을 발급/전달해줍니다.

그럼 웹 브라우저 측에서 해당 세션/토큰 정보를 받아 간직하고 있다가

새로운 request를 보낼 때마다 **인가(Authorization)**를 위해 해당 세션/토큰을 함께 보냅니다.

인증과 인가

세션 기반 인가와 토큰 기반 인가에 대해 알아보기 이전에 먼저, 인증과 인가가 무엇인지 부터 알아야할 필요가 있다. 인증과 인가를 같거나 비슷한 개념이라고 생각하는 사람들이 많을텐데, 엄밀하게는 서로 다른 개념이다. 인증과 인가는 요약하자면 시스템의 자원을 적절하고 유효한 사용자에게 전달하고 공개하는 방법이다.

인증에는 클라이언트의 쿠키 저장소에 Key-Value 형식의 문자열 방식을 저장시켜 고유 정보 식별 가능!

인증 (Authentication)

인증은 쉽게 말하자면, 로그인 이다. 클라이언트가 자기자신이라고 주장하고 있는 사용자가 맞는지를 검증하는 과정이다. 예를 들어 로그인 화면에서 내가 유저 아이디를 USER1 로 입력하고 패스워드를 입력해 제출하면, 서버에서는 내가 진짜로 USER1 이라는 유저가 맞는지 확인한다.

인가 (Authorization)

인가는 인증 작업 이후에 행해지는 작업으로, 인증된 사용자에 대한 자원에 대한 접근 확인 절차를 의미한다. 쉽게 말해서 권한! 기본 장고에서는 유저가 동일한지 함수로 체크했지만

DRF에서는 Permission를 통해 권한을 부여했음

여기에 일반 유저인 USER1과 USER2가 있다. 일반 유저인 USER1 은 글 작성, 조회, 수정, 삭제 등 일반적인 작업에 대한 권한이 부여되어 있다. 하지만 USER1 은 USER2가 작성한 글을 수정하거나 제거할 수는 없다. 타인의 리소스에 대해서는 인가되어 있지 않기 때문이다. 또한 USER1과 USER2 는 모두 관리자 페이지에 접속할 수 없다. 일반 유저는 관리자 페이지에 대해 인가되어 있지 않기 때문이다.

쿠키-세션-토큰(JWT)

1.쿠키 (Cookie) - 클라이언트의 브라우저에 설치

쿠키는 Key-Value 형식의 문자열 덩어리이다.

클라이언트가 어떠한 웹사이트를 방문할 경우, 그 사이트가 사용하고 있는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일이다.

각 사용자마다의 브라우저에 정보를 저장하니 고유 정보 식별이 가능한 것이다.

Cookie 인증방식의 단점

  • 보안에 취약함 가장 큰 문제 .요청 시 쿠키의 값을 그대로 보내기 때문에 유출 및 조작 당할 위험이 존재한다.
  • 웹 브라우저마다 쿠키에 대한 지원 형태가 다르기 때문에 브라우저간 공유가 불가능하다.
  • 쿠키에는 용량 제한이 있음
  • 쿠키 사이즈가 크면 네트워크 부하가 심해짐.

2. 세션 Session - 서버에 저장

이러한 쿠키의 보안적인 이슈 때문에, 세션은 비밀번호 등 클라이언트의 민감한 인증 정보를 브라우저가 아닌 서버 측에 저장하고 관리한다.

서버의 메모리에 저장하기도 하고, 서버의 로컬 파일이나 데이터베이스에 저장하기도 한다.

핵심 골자는 민감한 정보는 클라이언트에 보내지 말고 서버에서 모두 관리한다는 점이다.

 

Session 방식의 단점

  • 쿠키를 포함한 요청이 외부에 노출되더라도 세션 ID 자체는 유의미한 개인정보를 담고 있지 않는다.그러나 해커가 세션 ID 자체를 탈취하여 클라이언트인척 위장할 수 있다는 한계가 존재한다. (이는 서버에서 IP특정을 통해 해결 할 수 있긴 하다)
  • 서버에서 세션 저장소를 사용하므로 요청이 많아지면 서버에 부하가 심해진다.

3.Token 인증

토큰 기반 인증 시스템은 클라이언트가 서버에 접속을 하면 서버에서 해당 클라이언트에게 인증되었다는 의미로 '토큰'을 부여한다.

이 토큰은 유일하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때 요청 헤더에 토큰을 심어서 보낸다.

그러면 서버에서는 클라이언트로부터 받은 토큰을 서버에서 제공한 토큰과의 일치 여부를 체크하여 인증 과정을 처리하게 된다.

기존의 세션기반 인증은 서버가 파일이나 데이터베이스에 세션 정보를 가지고 있어야 하고 이를 조회하는 과정이 필요하기 때문에 많은 오버 헤드가 발생한다.

하지만 토큰은 세션과는 달리 서버가 아닌 클라이언트에 저장되기 때문에 메모리나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜 수 있다.

토큰 자체에 데이터가 들어있기 때문에 클라이언트에서 받아 위조되었는지 판별만 하면 되기 떄문이다.

토큰은 앱과 서버가 통신 및 인증 할 때 가장 많이 사용된다.

왜냐하면 웹에는 쿠키와 세션이 있지만 앱에서는 없기 때문이다.

Token 방식의 단점

  1. 쿠키/세션과 다르게 토큰 자체의 데이터 길이가 길어, 인증 요청이 많아질수록 네트워크 부하가 심해질수 있다.
  2. Payload 자체는 암호화되지 않기 때문에 유저의 중요한 정보는 담을 수 없다.
  3. 토큰을 탈취당하면 대처하기 어렵다. (따라서 사용 기간 제한을 설정하는 식으로 극복한다

4.JWT Token

JWT(JSON Web Token)란 인증에 필요한 정보들을 암호화시킨 JSON 토큰을 의미한다.

그리고 JWT 기반 인증은 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식이다

JWT는 JSON 데이터를 Base64 URL-safe Encode 를 통해 인코딩하여 직렬화한 것이며, 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 들어있다.

따라서 사용자가 JWT 를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 돌려준다.

 

 

JWT 구조

JWT는 . 을 구분자로 나누어지는 세 가지 문자열의 조합이다.

.을 기준으로 좌측부터 HeaderPayloadSignature를 의미한다.

JWT 장점

  1. Header와 Payload를 가지고 Signature를 생성하므로 데이터 위변조를 막을 수 있다.
  2. 인증 정보에 대한 별도의 저장소가 필요없다.
  3. JWT는 토큰에 대한 기본 정보와 전달할 정보 및 토큰이 검증됬음을 증명하는 서명 등 필요한 모든 정보를 자체적으로 지니고 있다.
  4. 클라이언트 인증 정보를 저장하는 세션과 다르게 , 가 되어 서버 확장성이 우수해질 수 있다.서버는 무상태
  5. 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능하다. (쿠키와 차이)
  6. OAuth의 경우 Facebook, Google 등 소셜 계정을 이용하여 다른 웹 서비스에서도 로그인을 할 수 있다.
  7. 모바일 어플리케이션 환경에서도 잘 동작한다. (모바일은 세션 사용 불가능)

JWT 단점

  1. Self-contained : 토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있다.
  2. 토큰 길이 : 토큰의 Payload에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있다.
  3. Payload 인코딩 : payload 자체는 암호화 된 것이 아니라 BASE64로 인코딩 된 것이기 때문에, 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, payload에 중요 데이터를 넣지 않아야 한다.
  4. Store Token : stateless 특징을 가지기 때문에, 토큰은 클라이언트 측에서 관리하고 저장한다. 때문에 토큰 자체를 탈취 당하면 대처하기가 어렵게 된다.

JWT의 Access Token / Refresh Token 방식

JWT도 제 3자에게 토큰 탈취의 위험성이 있기 때문에, 그대로 사용하는것이 아닌 Access Token, Refresh Token 으로 이중으로 나누어 인증을 하는 방식을 현업에선 취한다.

Access Token 과 Refresh Token은 둘다 똑같은 JWT이다. 다만 토큰이 어디에 저장되고 관리되느냐에 따른 사용 차이일 뿐이다.

  • Access Token : 클라이언트가 갖고 있는 실제로 유저의 정보가 담긴 토큰으로, 클라이언트에서 요청이 오면 서버에서 해당 토큰에 있는 정보를 활용하여 사용자 정보에 맞게 응답을 진행
  • Refresh Token: 새로운 Access Token을 발급해주기 위해 사용하는 토큰으로 짧은 수명을 가지는 Access Token에게 새로운 토큰을 발급해주기 위해 사용. 해당 토큰은 보통 데이터베이스에 유저 정보와 같이 기록.

 

개념이 생소할수 있지만 Access Token은 우리가 지금까지 설명한 JWT를 말하는 것이라고 보면 된다.

정리하자면, Access Token은 접근에 관여하는 토큰, Refresh Token은 재발급에 관여하는 토큰의 역할로 사용되는 JWT인 것이다.

참조- https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리

참조 - https://hudi.blog/cookie-and-session/