로그인 그리고 세션과 토큰

Habyte·2023년 6월 28일
0

프론트 기본 개념

목록 보기
1/2

서론


여러 프로젝트를 진행하면서 로그인 기능을 구현해야 하는 상황들을 마주했다. 가장 기본적인 기능이면서 보안적으로 중요한 로그인 기능. 아직까지도 제대로 알지 못하고 사용하고 있어 이번 기회에 개념 정리를 해보았다.

인증과 인가


먼저 두 개념의 차이는 다음과 같다:

  • 인증 (Authentication) : 사용자의 신원을 검증하는 단계
  • 인가 (Authorization) : 신원이 확인된 사용자에게 리소스에 접근할 수 있는 권한을 주는 단계

즉 웹에서 사용자가 웹사이트에 로그인 하는 과정을 인증, 로그인 한 사용자가 특정 리소스에 대한 접근 권한을 확인하는 과정을 인가 라고 할 수 있다.

문제점

그러면 어느 웹사이트에서 사용자가 로그인을 진행한다고 생각해보자. HTTP의 무상태성으로 인해 어떤 사용자가 인증을 받더라도 웹서버는 해당 사용자의 다음 요청에서 인증된 사용자라는 것을 알지 못한다. 즉, 매 요청마다 다시 인증을 해야 하는 문제가 발생한다.

이를 해결하기 위한 방법으로는 간단하게 브라우저에 유저 정보를 보관해 뒀다가 매 요청마다 해당 정보를 함께 전달하는 방법이 있다. 하지만 이는 민감한 유저정보를 모두 브라우저에 저장하는 보안적으로 아주 취약한 상태에 있다. 이러한 문제점을 해결하기 위한 방법에 세션과 토큰이 있다.

세션


세션 기반 인가는 사용자의 인증 정보가 서버의 세션 저장소에 저장되는 방식이다.

사용자가 로그인을 하고 유효한 사용자임이 인증이 되면 서버 세션 저장소에 인증 정보를 저장하게 되는데 이때 인증 정보는 Session ID 와 사용자 아이디로 이루어져 있다. 이후 서버에서 Session ID 를 담은 쿠키와 함께 응답을 보내고 브라우저 쿠키에 저장되게 된다. 이후 브라우저에 요청을 보낼 때 마다 헤더에 Session ID 담은 쿠키가 함께 전송되어 서버에서 전달받은 Session ID 와 세션 저장소를 비교해 유효한 인증 정보인지 확인하는 방식이다.

세션 작동 방식

토큰


토근 기반 인가는 인증 정보를 토큰의 형태로 클라이언트에 저장하고 있는 방식이다.

토큰 작동 방식

그중 가장 대표적인 JWT 토큰 방식에 대해서 알아보자.

Json Web Token (JWT) 란?

Json Web Token 은 세션방식과 큰 차이는 없이 인증에 필요한 모든 정보를 토큰에 담아 암호화 시킨뒤 사용한다. 여기서 가장 큰 차이는 JWT 는 해당 토큰을 서명해서 사용한다는 점이다. 즉, 개인/공개 키로 토큰에 서명을 한 경우 비밀키를 가진 서버에서 해당 토큰이 유효한지를 알수 있다는 말이다.

JWT의 구조

JWT 는 Header, Paload, Signiture 세가지 구성요소로 이루어져 있다. 이 세가지 구성요소는 . 을 기준으로 나누어 구분된다.

jwt 구조

헤더

헤더는 토큰 타입 그리고 해싱 알고리즘에 대한 정보를 담고 있다. 해싱은 Signiture 부분에서 사용되며 해싱 알고리즘으로는 일반 적으로 HMAC SHA256 혹은 RSA 가 사용된다.

{
  "typ": "JWT",
  "alg": "HS256"
}

페이로드

페이로드에는 토큰에 담을 정보가 담겨 있다. 여기에 담는 정보의 한 조각을 클레임(claim) 이라 부르고 키-값 형태를 가진다. 클레임에는 또 세가지 종류가 있다.

  • 등록된 클레임 : 이미 이름이 정해진 클레임들로 필요한 경우 선택적으로 사용하면 된다. 등록된 클레임에는 다음들이 있다.
    • iss: 발급자
    • sub: 제목
    • aud: 대상자
    • exp: 만료시간
    • nbf: 이 날짜가 지나기 전까지는 토큰이 처리되지 않음
    • iat: 토큰이 발급된 시간
    • jti: JWT의 고유 식별자
  • 공개 클레임 : 충돌을 방지하기 위한 이름을 자기고 있는 클레임으로서, 클레임 이름을 URI 형태로 지음.
    "https://gongibab.com/jwt_claims/is_user": true
  • 비공개 클레임 : 아무 규칙없이 임의로 명명해서 사용하는 클레임. 따라서 이름 중복으로 인한 충돌을 주의 해야함:
    "username": "gongibab"

따라서 해당 클레임들을 포함한 예제 페이로드는 다음과 같다:

{
    "iss": "gongibab.com",
    "exp": "1485270000000",
    "https://gongibab.com/jwt_claims/is_user": true,
    "userId": "11028373727102",
    "username": "gongibab"
}

서명

서명은 헤더의 인코딩 값 그리고 페이로드의 인코딩 값을 합친 뒤 주어진 비밀키로 암호화하여 해쉬를 생성한다. 이 과정을 수도 코드로 나타내면 다음과 같다:

HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

위 과정들에서 만들어진 값들을 각각 base64 로 인코딩하여 .을 중간자로 합쳐주면 JWT 토큰이 완성된다.

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ2ZWxvcGVydC5jb20iLCJleHAiOiIxNDg1MjcwMDAwMDAwIiwiaHR0cHM6Ly92ZWxvcGVydC5jb20vand0X2NsYWltcy9pc19hZG1pbiI6dHJ1ZSwidXNlcklkIjoiMTEwMjgzNzM3MjcxMDIiLCJ1c2VybmFtZSI6InZlbG9wZXJ0In0.WE5fMufM0NDSVGJ8cAolXGkyB5RmYwCto1pQwDIqo2w

세션 vs 토큰


세션토큰
사이즈쿠키 헤더에 세션 아이디만 담아 보내면 됨으로 적은 트래픽을 소모함헤더, 페이로드, 서명등 세션 아이디에 비해 훨씬 많은 정보를 담고 있다. 따라서 훨씬 더 많은 트래픽을 소모함
안정성과 보안모든 인증 정보를 서버에서 관리하기에 조금더 보안 측면에서 유리하다. 세션 아이디가 탈취된다고 해도 서버에서 해당 세션을 삭제하면 된다. 인증 정보가 서버 세션에 모두 저장되어 있어서 아무 데이터나 저장 가능하다.서버에서 인증정보를 관리하지 않기 때문에 토큰이 만료되기 전까지 속수무책이다.페이로드가 암호화 되있지 않아서 누구나 내용을 볼 수 있다. 따라서 민감한 데이터는 토큰에 저장할 수 없다.
서버 부담 및 확장성사용자가 많아 질 수록 세션 데이터 양이 늘어나면 서버 부담도 비례해 커진다.일반적으로 웹 서버 확장은 수평적으로 일어나는데 이때 세션 기반 인증은 세션 불일치 문제를 겪게 된다. 따라서 세션 스토리지 외부 분리 등의 작업이 필요해진다.클라이언트에 인증정보를 저장되어 있으므로 세션 방식에 비해 서버 부담 측면에서 조금 더 유리하다. 위와 같은 이유로 HTTP 의 비상태성을 그대로 활용하여 높은 확장성을 가질 수 있다.

Refresh Token


위에서 언급한 대로 JWT 토큰은 한번 발급한 토큰에 대해서는 제어권이 없고 탈취돼더라도 토큰 만료이전까지 어떻게 할 방법이 없다.

그렇다고 유효기간을 아주 짧게 하자니 사용자가 지속적으로 로그아웃이 되며 사용자 경험에 악영향을 미칠 수 밖에 없다. 이런 문제들을 해결하기 위해 도입된 것이 refresh token 이다.

Refresh Token 의 목적과 매커니즘

Access Token 의 유효 기간을 짧게 하여 보안을 강화하면서도 사용자에게 잦은 로그아웃 경험을 주지 않도록 하는 것이다. Access Token은 리소스에 접근하기 위해서 사용하되, Refresh Token은 기존에 클라이언트에 저장되 있던 Access Token이 만료되었을 때 재발급 받기 위해 사용된다.

Refresh Token은 서버 데이터베이스에 사용자와 매핑되어 저장되어 인증에 사용된다.

Refresh Token의 매커니즘은 다음과 같다:

  1. 클라이언트가 로그인을 요청하고 성공하면, 서버는 Access Token Refresh Token을 담아 응답한다.
  2. 클라이언트는 인가가 필요한 요청에 Access TokenRefresh Token 을 실어 보낸다.
  3. 만약Access Token이 만료 되면, Refresh Token을 사용하여 새로운 Access Token을 발급 받는다.

리프레시 토큰 작동개념
출처 : https://www.rfc-editor.org/rfc/rfc6749.html


레퍼런스

인증과 인가 (권한 부여) 비교 – 특징 및 차이점 | Okta Identity Korea
[10분 테코톡] 🎡토니의 인증과 인가
[JWT] 토큰(Token) 기반 인증에 대한 소개
[JWT] JSON Web Token 소개 및 구조
세션 기반 인증과 토큰 기반 인증 (feat. 인증과 인가)
Access Token의 문제점과 Refresh Token
What Are Refresh Tokens and How to Use Them Securely

profile
인생 저장소

0개의 댓글