만두의 부트캠프 🤔
  • [팀프로젝트] JWT토큰
    2024년 01월 06일 22시 24분 03초에 업로드 된 글입니다.
    작성자: 만두33

     

    멘토링 시간... 인증은 어떻게 하시나요? JWT 토큰..?

    ... 또 나만 잘 모르네...;; 🫨

    지금부터 알면됨ㅋ 😂

    유어클래스랑 구글링 유어클래스로 기본적으로 토큰에 대해 알아봤다. 


    ✔️ JWT 토큰

    JWT 는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON입니다.
    전자 서명은 JSON 의 변조를 체크 할 수 있게되어 있습니다.

    JWT( JSON Web Token)은 정보를 안전하게 전송하기 위한 컴팩트하고 자체 포함 형식의 표준입니다.
    JWT는 특히 웹에서 정보를 주고받을 때 사용되며, 서버와 클라이언트 간의 정보를 안전하게 인코딩하여 전송할 수 있게 해줍니다.

    JWT의 구조는 세 부분으로 나뉩니다:

    Header(헤더):
    토큰의 유형과 해시 알고리즘 정보를 포함합니다.
    Base64로 인코딩되어 있습니다.

    Payload(내용):
    토큰에 포함되는 클레임(정보)이 담겨 있습니다.
    Base64로 인코딩되어 있으며, 여러 개의 클레임을 포함할 수 있습니다.

    Signature(서명):
    토큰의 유효성을 검증하기 위한 서명입니다.
    헤더와 페이로드, 시크릿 키를 사용하여 생성됩니다.

    JWT는 서버에서 사용자의 로그인 정보를 담고 있는 토큰을 생성하고, 클라이언트에게 전달합니다.
    클라이언트는 이 토큰을 이용하여 서버에 자신을 인증하거나, 특정 리소스에 접근할 권한이 있는지 확인합니다.
    이는 사용자가 로그인 상태를 유지하고, 서버와 클라이언트 간에 안전하게 정보를 교환하는 데 사용됩니다.

    간단한 예를 들면,
    사용자가 로그인하면 서버에서 해당 사용자의 ID와 권한을 담은 JWT를 생성하고,이를 클라이언트에게 전달합니다.
    클라이언트는 이 토큰을 이용하여 서버에게 요청을 보낼 때 자신의 신원을 증명하게 됩니다.
    이를 통해 세션 관리를 서버에서 클라이언트로 이전하여 확장성을 높일 수 있습니다.

    ✔️ 기존 토큰 방식과의 차이

    기존 방식 JWT 토큰 방식
    기존의 토큰 방식 인증의 토큰은 이후의 모든 서비스 호출에 사용됩니다.
    서비스를 받기 위해서는 토큰의 유효성을 확인하여 세부 정보를 쿼리해야합니다.
    참조에 의한 호출(By Reference) 형태로 모든 서비스는 항상 상호 작용할 때 다시 접속해야합니다.

    JWT 와 같이 값에 의한 호출이 가능한 토큰이 필요합니다.
    토큰이 필요한 모든 정보를 포함하고 있어 참조(적어도 인증 및 권한 부여를 위해)가 필요없기 때문에 마이크로서비스 자체에서 유효성을 검증 합니다.
    이것이 JWT ( JSON Web Token )의 목적입니다!

    ✔️ JWT 절차

    *더보기는 물음표살인마의 질문목록

    1. 사용자 로그인 시도:
      • 사용자가 id와 password를 입력하여 로그인을 시도합니다.
      • 이 정보는 안전한 방식(예: HTTPS)으로 서버에 전송됩니다. 
      • 더보기
        Q. 안전한 방식이 뭐야? 
        A.
        "안전한 방식"이란 말은 주로 데이터를 전송하거나 통신할 때 보안을 강화하기 위한 방법을 의미합니다. 
        여기서 사용자의 id와 password를 안전하게 전송하기 위한 방법으로는 HTTPS(SSL/TLS)가 가장 널리 사용되는 방법 중 하나입니다.

        HTTPS는 일반 HTTP 통신을 암호화하여 보안을 제공하는 프로토콜입니다. 
        이를 통해 데이터가 중간에서 가로채지거나 조작되지 않도록 보호할 수 있습니다. 
        사용자의 민감한 정보인 id와 password를 전송할 때에는 HTTPS를 사용하여 데이터의 기밀성과 무결성을 보장하는 것이 좋습니다.

        그 외에도 VPN(Virtual Private Network), SSH(Secure Shell) 등의 방법도 있지만, 
        일반적으로 웹 애플리케이션에서는 HTTPS를 사용하는 것이 보편적입니다.
    2. 서버에서 Access Token 발급:
      • 서버는 사용자의 로그인 정보를 확인하고, 유효하다면 서버 내부에서 사용자를 식별할 수 있는 고유한 정보(ID 등)와 함께 JWT Access Token을 생성합니다.
      • 이때, 서버는 사전에 정의한 비밀 키(secret key)를 사용하여 서명합니다.

      • 더보기
        Q. 비밀 키가 뭐야?
        A. 비밀 키(또는 시크릿 키)는 암호화와 서명을 포함한 암호학적 작업에서 사용되는 비밀 값입니다. 
        이 키는 정보를 안전하게 보호하고, 서명을 생성하거나 검증하며, 데이터를 암호화하거나 복호화하는 데 사용됩니다.

        JWT(JSON Web Token)의 Access Token 생성 시, 서버는 비밀 키를 사용하여 토큰을 서명합니다. 
        이 서명은 토큰이 변경되지 않았음을 확인하고, 토큰이 유효한지 확인하는 데 사용됩니다. 
        서버가 발급한 토큰을 클라이언트가 제출할 때, 서버는 이 토큰을 검증하기 위해 동일한 비밀 키를 사용합니다.

        비밀 키는 서버 내부에서 안전하게 보관되어야 합니다. 
        외부에서 유출되면 악의적인 공격자가 토큰을 위조하거나 변조할 수 있기 때문에 보안 상의 중요한 역할을 합니다.
         따라서 비밀 키는 안전한 저장소에 보호되어야 하며, 외부와의 공유를 최소화해야 합니다.
        --------------------------------------------------------------------------------------------------------
        Q. 비밀 키를 만들때 위의 여러 방법을 한번에 섞어서 써도 가능?
        A. 예, 안전한 비밀 키를 생성하는 데에는 여러 방법을 조합하여 사용하는 것이 일반적입니다. 
        랜덤 문자열 생성에는 암호학적으로 안전한 난수 생성기 또는 랜덤 문자열을 생성하는 라이브러리를 사용하는 것이 좋습니다. 이를 조합하여 안전성을 높일 수 있습니다.

        여러 방법을 섞어 사용하는 것은 안전성을 향상시킬 수 있지만, 
        기본적으로 안전한 방법을 선택하는 것이 중요합니다. 
        대부분의 언어와 프레임워크에서는 안전한 랜덤 문자열 생성을 위한 라이브러리나 함수를 제공하고 있습니다.

        예를 들어, Node.js에서는 crypto 모듈을 사용하여 안전한 난수를 생성할 수 있고, 
        Python에서는 secrets 모듈이나 os.urandom() 함수를 사용할 수 있습니다. 
        이러한 함수들은 안전한 난수를 생성하는 데에 적합한 방법을 제공합니다.
    3. JWT 토큰 전달:
      • 서버는 생성한 JWT Access Token을 클라이언트에게 전달합니다.
      • 클라이언트는 이 토큰을 안전한 방식으로 저장하고, 향후 서버에 대한 요청에 이 토큰을 포함시켜 전송합니다.
      • 더보기
        Q. 클라이언트가 토큰을 안전한 방식으로 저장하는 방법의 예시?
        A. 클라이언트가 JWT Access Token을 안전하게 저장하는 방법 중 하나는 웹 브라우저의 localStorage나 sessionStorage를 사용하는 것입니다. 다음은 간단한 예시입니다.

        // 토큰 저장
        localStorage.setItem('accessToken', 'your_jwt_access_token');

        // 토큰 가져오기
        const accessToken = localStorage.getItem('accessToken');

        localStorage는 브라우저의 영구 저장소로, sessionStorage는 세션 동안만 유지되는 임시 저장소입니다. 
        이들을 사용하면 클라이언트 측에서 토큰을 안전하게 저장하고, 필요할 때 가져올 수 있습니다.

        하지만 주의해야 할 점은 XSS(크로스 사이트 스크립팅) 공격에 취약할 수 있다는 것입니다.
        XSS 공격을 방지하기 위해선 특히 중요한 정보를 담은 토큰은 HttpOnly 속성이 설정된 쿠키에 저장하는 것이 안전합니다.
        이는 JavaScript로 쿠키에 접근하는 것을 방지할 수 있습니다.
        그러나 이 방법을 사용하려면 클라이언트와 서버가 같은 도메인에 있어야 합니다.
        --------------------------------------------------------------------------------------------------------
        Q. sessionStorage는 세션 동안만 유지되는 임시 저장소입니다. 여기서 "세션동안"이 어떤 기간이야?
        A.
        "세션 동안"이란 사용자가 브라우저를 열고 로그인한 후 브라우저를 닫을 때까지를 의미합니다. 
        세션은 사용자가 브라우저를 열고 로그인한 순간부터 그 브라우저를 닫을 때까지의 일련의 상호 작용을 나타냅니다. 
        브라우저를 닫으면 sessionStorage에 저장된 데이터는 삭제됩니다.

        세션 기간은 사용자가 로그인한 상태를 유지하는 동안만 데이터가 유지되며,
         브라우저를 닫으면 해당 세션의 데이터가 소멸합니다.
         이는 sessionStorage의 특성으로, 브라우저 세션이 끝날 때까지만 데이터가 유지되고 다시 열리면 새로운 세션과 새로운 저장 공간이 생성됩니다.
    4. 클라이언트에서 API 요청:
      • 클라이언트는 API를 요청할 때, HTTP 헤더의 Authorization에 발급받은 JWT Access Token을 포함시켜 서버에게 전송합니다.
      • 더보기
        Q. API를 요청?
        A. API(애플리케이션 프로그래밍 인터페이스)를 요청한다는 것은 클라이언트(사용자 브라우저, 애플리케이션 등)가 서버에게 데이터를 요청하는 행위를 의미합니다. 이 요청은 일반적으로 HTTP 또는 HTTPS 프로토콜을 사용하여 이루어집니다.

        API 요청은 클라이언트가 서버로부터 특정한 기능이나 데이터를 얻기 위해 서버에게 명시적인 요청을 보내는 것을 말합니다. 이 요청은 특별한 형식을 가지며, 서버는 이 요청을 받아들여 적절한 응답을 반환합니다.

        예를 들어, 웹 애플리케이션이 특정 서버의 데이터베이스에서 정보를 가져오기 위해 API 요청을 보낼 수 있습니다. 이 때 클라이언트가 서버에게 "해당 데이터베이스에서 이 정보를 가져다주세요"와 같은 형태로 요청하게 되고, 서버는 그에 맞는 응답을 생성하여 클라이언트에게 반환합니다.
    5. 서버에서 토큰 확인 및 데이터 반환:
      • 서버는 클라이언트로부터 받은 JWT Access Token을 확인합니다.
      • 토큰이 유효하고 서명이 올바르다면, 서버는 토큰의 Payload로부터 사용자 정보를 추출하여 해당 API에 대한 요청을 처리하고 결과 데이터를 반환합니다.
      • 더보기
        Q. 토큰의 유효기간?
        A.
        JWT Access Token의 유효기간은 토큰을 생성하는 서버 측에서 설정됩니다. 
        이 기간은 토큰이 발급된 후 일정 시간 동안 유효하다는 것을 나타냅니다. 
        유효기간이 지난 토큰은 더 이상 사용할 수 없으며, 새로운 토큰이 필요합니다.

        서버는 토큰의 유효기간을 설정할 때, 보안 및 사용자 경험을 고려하여 적절한 값을 선택합니다. 
        일반적으로 짧은 기간으로 설정하여 보안을 강화하고, 
        유저가 자주 재인증을 해야 하는 경우를 방지합니다. 
        하지만 너무 짧게 설정하면 사용자 경험이 나빠질 수 있으므로 적절한 균형을 찾아야 합니다.

        토큰의 유효기간은 "exp" (expiration time) 클레임을 사용하여 설정됩니다. 
        이 클레임은 유효기간을 나타내는 타임스탬프로 표현됩니다. 
        클라이언트나 서버가 이 유효기간을 확인하여 토큰의 유효성을 판단합니다.
        --------------------------------------------------------------------------------------------------------
        Q. exp 클레임 예시
        A.
        "exp" 클레임은 JWT 토큰 내에서 토큰의 만료 시간을 나타냅니다. 
        이 클레임은 UTC 기준의 UNIX 타임스탬프로 표현되며, 
        해당 시간 이후에는 토큰이 더 이상 유효하지 않다는 것을 나타냅니다.

        예를 들어, 만료 시간이 2024년 1월 1일 00:00:00 (UTC)인 경우의 "exp" 클레임은 해당 시간의 UNIX 타임스탬프 값이 됩니다.

        {
          "exp": 1641043200,
          // 다른 클레임들...
        }
        위의 예시에서 "exp" 값인 1641043200는 2024년 1월 1일 00:00:00 (UTC)을 나타냅니다. 
        클라이언트나 서버는 이 값과 현재 시간을 비교하여 토큰이 유효한지 확인합니다. 
        만료 시간이 지나면 토큰은 더 이상 사용할 수 없습니다.

        토큰 라이브러리를 사용하는 경우 대부분의 라이브러리에서는 만료 시간을 설정하는데 도움을 주는 함수 또는 옵션을 제공합니다. 
        이러한 함수나 옵션을 사용하여 토큰의 만료 시간을 쉽게 설정할 수 있습니다.
    6. 서버의 토큰 검증:
      • 인증이 필요한 경로에 접근할 때, 서버는 Authorization 헤더에 유효한 JWT Access Token이 존재하는지 확인합니다.
      • 서버는 비밀 키를 사용하여 서명을 확인하고 토큰의 만료 여부 등을 체크합니다.

     

    이 과정을 통해 사용자는 로그인 정보를 서버에 저장하지 않고도 토큰을 통해 인증되어 API에 접근할 수 있게 됩니다. 이는 보안과 확장성 측면에서 일반적으로 유용한 방식 중 하나입니다.


    JWT에는 필요한 모든 정보를 토큰에 포함하기 때문에 데이터베이스과 같은 서버와의 커뮤니케이션 오버 헤드를 최소화 할 수 있습니다.
    Cross-Origin Resource Sharing (CORS)는 쿠키를 사용하지 않기 때문에 JWT를 채용 한 인증 메커니즘은 두 도메인에서 API를 제공하더라도 문제가 발생하지 않습니다.
    일반적으로 JWT 토큰 기반의 인증 시스템은 위와 같은 프로세스로 이루어집니다.
    처음 사용자를 등록할 때 Access token과 Refresh token이 모두 발급되어야 합니다.


    ✔️ JWT 사용되는곳

    JWT는 주로 사용자 인증 및 권한 관리에 사용되지만, 특정한 상황에 따라 다양하게 활용될 수 있습니다.
    주로 다음과 같은 상황에서 JWT가 사용될 수 있습니다:

    1. 로그인 및 세션 유지: 사용자가 로그인하면 서버에서 JWT를 생성하고 이를 클라이언트에게 전달합니다.
      클라이언트는 이 JWT를 저장하고, 이후의 요청에서는 이를 통해 자신이 누구인지 증명할 수 있습니다.
      이로써 세션을 서버에 저장하지 않고도 사용자를 식별할 수 있습니다.

    2. 사용자 권한 부여: JWT의 "roles" 클레임을 통해 특정 사용자에 대한 권한 정보를 효과적으로 전달할 수 있습니다.
      클라이언트가 서버로부터 받은 JWT를 사용하여 권한이 필요한 API나 리소스에 접근할 수 있습니다.

    3. 사용자 정보 전달: JWT에는 사용자의 추가 정보(예: 이메일, 이름, 프로필 사진 등)를 넣어 전달할 수 있습니다.
      이를 통해 클라이언트는 로그인 후에도 사용자에 대한 추가 정보를 갖게 됩니다.

    4. 비밀 데이터 전송: JWT는 서명을 통해 안전하게 전달되므로, 클라이언트와 서버 간의 안전한 통신을 위해 사용될 수 있습니다.
      예를 들어, 클라이언트가 서버에 데이터를 전송하고 이를 검증하는 데에 활용될 수 있습니다.

    5. 다중 서비스 간의 인증: 여러 서비스가 하나의 사용자 인증을 공유할 때,
      JWT를 사용하여 각 서비스 간에 사용자 인증을 전달할 수 있습니다.

    단, 보안상의 이유로 중요한 정보를 JWT에 담을 때에는 해당 정보를 안전하게 전달할 수 있도록 적절한 조치가 필요하며,
    특히 민감한 정보에 대해서는 암호화를 고려해야 합니다.

     

     
    일단 여기까지... JWT 토큰에 대해서 기본정리🫠
     

    참고사이트1

     

    JWT (JSON Web Token) 이해하기와 활용 방안 - Opennaru, Inc.

    JWT 는 JSON Web Token의 약자로 전자 서명 된 URL-safe (URL로 이용할 수있는 문자 만 구성된)의 JSON입니다.JWT는 속성 정보 (Claim)를 JSON 데이터 구조로 표현한 토큰으로 RFC7519 표준 입니다.

    www.opennaru.com

    참고사이트2 

    참고사이트2 추천👍

     

    [JWT] JSON Web Token 소개 및 구조 | VELOPERT.LOG

    지난 포스트에서는 토큰 기반 인증 시스템의 기본적인 개념에 대하여 알아보았습니다. 이 포스트를 읽기 전에, 토큰 기반 인증 시스템에 대해서 잘 모르시는 분들은 지난 포스트를 꼭 읽어주세

    velopert.com

     

    댓글