ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • # TIL_쿠키, 세션, 토큰, JWT 풀어서 쓴 개념 정리
    TIL (Today I Learned) 2023. 11. 9. 00:33

    # Auty(인증)

    Auty(인증)을 통해 서비스 사용자를 검증할 수 있습니다. Auty(인증)을 구현하기 위해 쿠키(Cookie), 세션(Session), 토큰(Token) 그리고 JWT(JSON Web Token)을 이용해야 합니다. 


    # 쿠키(Cookie)

    쿠키는 서버가 사용자의 브라우저에 데이터를 저장할 수 있는 방법입니다. 이는 사용자 관련 정보를 기억하기 위한 용도로 사용됩니다. 사용자가 웹사이트에 방문하면 브라우저가 서버에 요청을 보내고, 서버는 응답을 반환할 때 사용자의 정보 및 필요한 페이지 데이터를 함께 반환합니다. 브라우저는 이러한 데이터를 쿠키로 저장하고, 해당 웹사이트를 방문할 때마다 해당 쿠키를 서버로 전송합니다.

    쿠기는 도메인에 따라 제한될 수 있으며, 유효기간이 있어 서버에서 정한 기간 동안 유효합니다. 쿠키는 인증뿐만 아니라 다양한 정보를 저장할 수 있습니다. 예를 들면 웹사이트의 언어 설정을 변경하면 서버는 해당 언어를 쿠키에 저장하고 이후 사용자가 해당 웹사이트를 방문할 때, 쿠키는 서버로 전송되며 서버는 해당 설정에 따른 페이지를 제공합니다. 

     


    # 세션(Session)

    세션은 서버 측에서 사용자 정보를 유지하고 상태를 관리하기 위한 방법 중 하나입니다. 사용자가 웹 사이트에 로그인하면 서버는 해당 사용자에 대한 세션을 생성하고 세션 ID를 클라이언트에게 제공합니다. 이 세션 ID는 일반적으로 쿠키를 통해 클라이언트에 저장됩니다. 따라서 사용자가 다른 페이지로 이동할 때, 클라이언트는 세션 ID를 서버에 전송하고, 서버는 해당 세션 ID를 사용하여 사용자를 식별하고 해당 세션에 저장된 정보를 활용합니다. 이를 통해 사용자 상태를 유지하고 인증할 수 있습니다.

     

    # 토큰(Token)

    토큰은 서버에서 생성한 문자열로, 클라이언트(사용자 브라우저 또는 앱)에게 전달되어 서버와 클라이언트간의 인증을 수행하는데 사용됩니다. 토큰은 서버로 요청을 보낼 때 함께 제출되어 서버는 해당 토큰을 검증하고, 해당 토큰에 연결된 사용자를 식별합니다. 쿠키와 달리 토큰은 서버에서 생성되고 클라이언트에게 전송되며, 클라이언트가 서버로 토큰을 제출하는 방식으로 작동합니다. 

     

    # 세션과 토큰이 필요한 이유

    http 웹사이트를 이용할때 쓰는 프로토콜은 Stateless입니다. Stateless는 서버로 가는 모든 요청이 이전 리퀘스트와 독립적으로 다뤄진다는 뜻입니다. 요청끼리는 연결이 없어 메모리가 없고, 요청이 끝나면 서버는 사용자가 누군지 잊어버립니다. 그렇기 때문에 요청 할 때 마다 사용자가 누구인지 알려줘야합니다. 

     

     

    이를 해결하는 방법 중 하나가 바로 세션(Session)입니다. 만약 `코인이`라는  유저명이 있고 로그인을 한다면 유저명과 비밀번호를 서버에 보냅니다. 그 후 비밀번호가 맞다면 서버는 세션 DB에 `코린이`라는 유저를 생성합니다. 

     

     

    그 후 비밀번호가 맞다면 서버는 세션 DB에 `코린이`라는 유저를 생성합니다.  

     

     

    해당 세션에는 별도의 ID를 가지고 있고 쿠키를 통해 브라우저로 돌아와서 저장됩니다. 

     

     

    따라서 같은 웹사이트의 다른 페이지를 이동하면 브라우저는 세션 ID를 갖고 있는 쿠키를 서버에 보내줍니다. 왜냐하면 쿠키는 자동으로 보내지기 때문입니다. 서버는 들어오는 쿠키를 보고 세션 ID와 함께 오는  쿠키를 확인합니다. 이때까지 서버는 사용자가 누구인지 모르고 있습니다. 세션 ID가 있는 쿠키를 지닌 요청이 있다는 것만 서버는 알고 있습니다. 

     

     

    이후 세션 ID를 가지고 있는 세션 DB를 서버가 확인 할 것이고 여기서 해당 ID는 유저명이 `코린이` 것이라는 것을 눈치챈 서버는 드디어 User가 누구인지 알게되고 `환영해요 "코린이"` 메시지를 띄우게 됩니다. 해당 요청이 끝이나고 다른 페이지로 넘어가면 이 모든 프로세스가 반복하게 됩니다. 

    여기서 기억해야 할 중요한 내용은 유저 정보는 모두 서버에 있다는 것입니다.  유저가 갖고있는 것은 세션 ID 뿐이며 쿠키는 그저 세션 ID를 전달하기 위한 매게체일 뿐입니다.

    +++추가 내용

    세션을 이용해 IOS와 Android 앱을 만들 수  있지만 쿠키는 사용할 수 없습니다. 쿠키는 네이티비 앱에는 없고  이 경우에는 토큰을 사용해야합니다. 토큰은 이상하게 생긴 String입니다.

    해당 토큰을 서버에 보내고, 서버는 세션 DB에서 해당 토큰과 일치하는 유저를 찾습니다. 세션에 대해 기억할 것은 현재 로그인한 유저들의 모든 세션 ID를 DB에 저장해야한다는 것입니다.  즉, 서버에 요청이 들어올 떄마다 서버는 쿠키를 받아서 세션 ID를 보고, 세션 ID와 일치하는 유저를 찾아야하며, 그제서야 다음 작업을 수행할 수 있습니다. 

    요청이 있을때 마다 DB찾고 유저가 늘어남에 따라 DB리소스가 더 필요해지는 상황이 오는데 이를 해결하고자 등장한 것이 JWT입니다.  JWT도 토큰 형식이며 유저 인증을 처리하면 세션 DB를 갖을 필요가 없고 서버는 유저를 인증한다고 많은 일을 하지 않도 됩니다. 

     

    #세션과 토큰의 차이점 정리

    1. 세션과 토큰 저장 위치 // 세션은 서버 측에서 사용자 정보를 저장하고 관리하며, 토큰은 클라이언트 측에서 정보를 저장합니다 .

    2. 유저 정보 저장 // 세션은 사용자 정보를 서버에 저장하므로 서버에 중요한 정보가 유지됩니다. 토큰은 주로 사용자 정보를 토큰 자체에 저장하지 않고, 서버는 토큰의 유효성 검사를 하여 사용자를 식별합니다. 

    3. 암호화 // 세션은 보안을 위해 서버 측에서 유지되므로 일반적으로 안전합니다. 토큰은 안전하게 다뤄져야하며, 암호화가 필요한 경우 토큰을 이용하여 데이터를 보호해야합니다.

    4. 확장성 // 세션은 서버 측에서 세션 정보를 저장하므로 사용자가 늘어날수록 서버 리소스가 필요합니다. 토큰은 클라이언트 측에서 상태를 유지하므로 서버 리소스에 대한 부담이 적습니다. 

    5. 웹 앱 외부에서의 사용 // 세션은 주로 웹 브라우저에서 사용됩니다. 토큰은 웹 앱 외에도 모바일 앱 및 다른 클라이언트 애플리케이션에서도 사용할 수 있습니다.

    6. 세션관리 // 세션 관리를 위해서는 서버에서 사용자 정보를 저장하고 세션 ID를 발급해야 합니다. 토큰은 사용자 인증 정보를 토큰에 포함하여 클라이언트에게 전달하는 방식이므로 서버의 세션 관리가 필요하지 않습니다. 


     # JWT(JSON Web Token)란?

    JWT는 "JSON 웹 토큰"을 뜻합니다. 이는 당사자 간의 정보를 JSON 개체로 표현하는 간결하고 독립적인 방법입니다. JWT는 클라이언트와 서버 간 또는 애플리케이션의 다양한 구성 요소 정보를 안전하게 전송하는데 사용되는 경우가 많습니다.

    1. 헤더 // 헤더는 일반적으로 토큰 유형(JWT)과 사용되는 서명 알고리즘(예: HMAC SHA256 또는 RSA)의 두 부분으로 구성됩니다.

    2. 페이로드 // 페이로드에는 클레임이 포함되어 있습니다. 클레임은 엔터티(일반적으로 사용자) 및 추가 데이터에 대한 설명입니다. 청구에는 등록, 공개, 개인 청구의 세 가지 유형이 있습니다.

    1) 등록된 주장: 필수는 아니지만 권장되는 사전 정의된 주장입니다. 일반적으로 등록된 클레임에는 "iss"(발급자), "exp"(만료 시간), "sub"(주제) 등이 포함됩니다.

    2) 공개 클레임: JWT를 사용하여 정의할 수 있는 사용자 지정 클레임이지만 IANA(Internet Assigned Numbers Authority)에 등록할 필요는 없습니다.

    3) 비공개 청구: 사용에 동의한 당사자 간에 정보를 공유하기 위해 생성된 사용자 지정 청구입니다.

    3. 서명 // 서명은 JWT의 보낸 사람이 누구인지 확인하고 메시지가 도중에 변경되지 않았는지 확인하는 데 사용됩니다. 이는 인코딩된 헤더와 페이로드를 가져와서 비밀 키와 결합하고 헤더에 지정된 알고리즘을 적용하여 생성됩니다.

    +++

    JWT는 웹 애플리케이션 및 API와 같은 인증 및 권한 부여 프로세스에 자주 사용됩니다. 사용자가 로그인하면 JWT 토큰을 받을 수 있습니다. 이 토큰은 사용자가 계속해서 사용자 이름과 비밀번호를 보낼 필요 없이 사용자를 인증하기 위한 후속 요청과 함께 전송될 수 있습니다. 그런 다음 서버는 JWT를 검증하고 디코딩하여 사용자를 식별하고 액세스 권한을 결정할 수 있습니다.

    JWT는 전송이 쉽고 다양한 프로그래밍 언어로 사용할 수 있으며 다양한 서명 알고리즘과 함께 사용하여 데이터 무결성을 보장할 수 있기 때문에 안전한 상태 비저장 인증에 널리 사용됩니다. 그러나 키에 액세스할 수 있는 사람은 누구나 유효한 JWT를 생성할 수 있으므로 토큰 서명에 사용되는 비밀 키를 안전하게 유지하는 것이 중요합니다.

     

    ## 로그인 예시를 통해 알아보는 JWT와 세션의 차이점

    유저명에 `코린이`를 로그인 하려면 유저명과 비밀번호를 서버에 보내야합니다. 

     

     

    여기까지는 전과 비슷하지만 유저명과 비밀번호가 일치한다면 서버는 DB에 정보를 생성하지 않습니다. 

     

     

     

    대신 서버는 유저의 ID를 가져다가 알고리즘을 이용해 작업을 할 겁니다. 예를 들면 알고리즘을 통해 사인을 하는데 해당 사인된 정보를 String 형태로 보냅니다. 

     

     

    ***JWT는 이렇게 생겼고, 보통 세션의 ID보다 훨씬 길게 이루어져 있습니다.

     

     

    왜냐하면 쿠키는 공간에 제약이 있는데 JWT는 제약이 없어서 엄청 길어도 되기 때문입니다. 동일하게 로그인한다고 했을 때 DB를 건드리는 대신에 정보를 사인하고 전달하는 것이 전부입니다.  

     

     

    이제 서버에서 요청을 보내려면 세션 ID와 비슷하게 해당 사인된 정보 혹은 토큰을 서버에 보내야합니다. 서버는 토큰을 받으면 해당 사인이 유효한지 체크함과 동시에 토큰이 조작되었는지 체크합니다.  만약 토큰이 유효하다면 서버는 사용자를 유저로 인증합니다. 

     

     

    이것이 세션과 가장 큰 차이점 입니다.  세션에서는 그냥 ID만 전달해주면 됩니다.

     

     

    세션에 대한 모든 정보는 세션 DB에 저장되어 있습니다. 그래서 페이지를 요청하면 서버는 세션 ID를 DB에서 찾으며 됩니다. 

     

     

    JWT에서 서버는 유저를 인증하는데 필요한 정보를 토큰에 저장합니다. 그리곤 해당 토큰을 사용자에게 전달해줍니다. 

     

     

    페이지를 요청하는 서버는 해당 토큰이 유효한지 검증하면 됩니다. 유효하지만 DB를 거칠 필요가 없습니다. 여기서 염두할 것은 JWT는 암호화 되지 않았습니다. 암호화 되었다면 아무도 읽을 수 없고 이해할 수 없습니다. JWT의 경우 누구나 열어서 [해당 컨텐츠를 볼 수 있습니다.  비밀번호를 JWT 안에 둬서도 안됩니다.   

     

     

    핵심은 토큰을 사인하고 이를 통해 유효한지 검증한다는 것입니다. 

     

    ## JWT와 세션의 장단점 

    세션을 사용하면 서버는 로그인 된 유저의 모든 정보를 저장합니다. 해당 정보를 이용하면 새로운 기능들을 추가할 수 있게 됩니다. 예를 들면 특정 유저를 쫓아내고 싶을 때, 섹션을 삭제해버리면 퇴장시킬 수 있습니다.  또 다른 예로는 인스타그램처럼 원하지 않는 디바이스를 강제로 로그아웃 시키거나 넷플릭스처럼 계정 공유 숫자를 제한 할 수도 있습니다. 

    이 모든 기능이 가능한  이유는 서버에 누가 로그인했는지 저장을 했고 세션 DB가 있기 때문입니다. 한가 지 조심해야 할 것은 이를 위해선 DB를 사고 유지해야합니다.  또한 유저가 늘어나면 늘어날 수록  DB도 커져야한다는 단점이 있습니다. 

    JWT를 사용하면 DB 구매할 필요는 없습니다. 하지만 위에서 설명드렸던 강제로그 아웃 기능, 강퇴 기능, 사용자 제한 기능 등을 할 수 없게 됩니다.  그렇다고 JWT가 단점만 있는 것은 아닙니다.

    데이터를 사인하고 유저에게 보내고 해당 데이터를 다시 돌려받을 때 유효성을 검증할 수 있습니다. DB없이 모든 것이 가능합니다.  JW가 들어간 예로 QR코드를 들 수 있습니다. JWT가 들어간 사용사례는 많지만 그중 하나가 세션이나 DB없이 유저를 인증하는 것입니다.  그렇기 때문에 JWT의 인증 제약만 잘 알아두면 됩니다. 

    만약 서비스가 더 거대해지고 유지 계정을 조금 더 잘 관리하고 싶다면 세션으로 옮겨가는 것이 현명한 판단입니다. 


    # 한 줄 정리

    쿠키는 그냥 옮기는 시스템 매게체입니다. 

    토큰은 서버가 기억하는 이상하게 생긴 텍스트며 ID카드처럼 서버에게 보여줘야합니다. 

    JWT는 정보를 갖고 있는 토큰이며, DB없이 검증할 수 있습니다. 

    => 유저 인증을 위해서 JWT 혹은 세션을 사용할 수 있습니다. 

     

Designed by Tistory.