ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Session과 JWT에 대해 알아보자잇! (feat.인증, 인가)
    💻 프로그래밍/Django 2022. 6. 20. 02:09

    안녕하세요! 개발자 JAY입니다!

    오늘은 sessionjwt 에 대해서 알아보려고 합니다. 추가적으로 인증(Authentication)인가(Authorization)에 대해서도 이야기해보려고 해요!

     

     

    1.  인증(Authentication)과 인가(Authorization)의 차이


    먼저 인증과 인가에 대해서 알아보겠습니다. 그 이유는 session, jwt가 인증과 관련이 있고 간혹 인증과 인가를 헷갈리는 분들이 계시기 때문이에요! 알고 보면 정말 간단합니다!

     

    출처: okta

    먼저 인증(Authentication)은 말 그대로 내가 누군지 인증하는 겁니다. 예를 들어 회사에 들어갈 때 얼굴 인증 등으로 본인이 누구인지 인증을 하게 되죠? ID/PW를 통해 로그인하는 과정과 비슷합니다.

     

    인가/권한 부여(Authorization)는 허용된 권한을 말합니다. 예를 들어 회사에 들어가도 사원이 사장실에 들어갈 수 없는 것처럼 이런 권한을 말하죠!

     

    여기까지 이해가 되셨을까요?!

     

     

    2.  Session (세션)


    세션쿠키로 세션데이터 조회

    로그인을 통해 인증이 되면, 이제 권한을 부여해야 합니다. 이런 권한을 부여하는 과정에서 사용되는 기술이 session과 jwt입니다.

     

    session은 클라이언트가 웹브라우저를 통해 웹서버에 접속한 시점부터 웹브라우저를 종료하는 시점까지 클라이언트가 누군지 구별하고 클라이언트에 따라 다른 권한을 주기 위해 사용되는 기술입니다.

     

    session정보는 DB에 저장되며 클라이언트는 sessionID를 가지고 있습니다. 클라이언트는 http request 요청 시 cookie에 sessionID를 저장하여 보내고 서버에서는 전달받은 sessionID로 DB에서 session을 조회합니다!

    (django에서는 SessionMiddleware에서 request를 통한 cookie와 session관리를 해줍니다)

     

    session의 장점은 더 이상 유저정보 등을 cookie에 직접 담아서 전송할 필요가 없다는 것입니다. cookie에 직접 유저정보를 담게되면 보안상 매우 위험합니다. 그리고 더이상 클라이언트에서 이런 유저 권한에 대한 정보를 가지고 있을 필요가 없고 서버에서 다 해주기 때문에 보안이 좀 더 좋아지고 클라이언트는 sessionID만 관리하면 됩니다.

    혹시나 sessionID가 탈취되더라도 DB에 저장된 session을 삭제하면 된다는 장점도 있습니다.

     

    단점으로는 서버 DB에 session정보가 저장되므로 DB 리소스를 잡아먹는다는 것입니다.  사용자가 많아질수록 리소스에 큰 부담이 가게 되죠! 그리고 여러  서비스를 유지할 때 A 서비스 session, B 서비스 session이 나누어져 있다면 해당 서비스의 session으로만 사용해야 한다는 단점이 있습니다.

     

     

    3.  JWT(Json Web Token)


    토큰 인증 과정

    JWT(JSON Web Token)는 서로 간의 정보를 JSON 개체로 안전하게 전송하기 위한 간결하고 자체 포함된 방법을 정의하는 개방형 표준( RFC 7519 )입니다. 이 정보는 디지털 서명되어 있으므로 확인하고 신뢰할 수 있습니다. JWT는 비밀( HMAC 알고리즘 사용)을 사용하거나 RSA 또는 ECDSA 를 사용하는 공개/개인 키 쌍을 사용하여 서명할 수 있습니다. (출처: jwt.io)

     

    한마디로, jwt는 session, cookie를 대신하는 의미가 있는 문자열 토큰입니다. 

     

    jwt의 구성을 알아보겠습니다!

     

    헤더(header)

    헤더 구조

    헤더에는 alg(알고리즘)과 type(타입)이 들어있습니다.

     

    페이로드(payload)

    페이로드 구조

    페이로드에는 사용자, 토큰 정보를 나타내는 클레임(claim)이라는 것으로 구성되어 있고,  key-value 형태입니다. 클레임에는 사용자 마음대로 아무런 값을 넣을 수 있습니다. (다만 클레임이 많아질수록 토큰의 길이가 길어집니다)

     

    클레임은 세 가지 종류로 되어있습니다.

     

    - registered claim : 필수는 아니지만 운영상 미리 정의된 클레임입니다.  iss (발급자), exp (만료 시간), sub (제목), aud (대상) 및 기타로 이루어져 있습니다.

     

    - public claim : JWT를 사용하는 사용자들이 마음대로 정의할 수 있습니다. 충돌을 방지하기 위해 IANA JSON Web Token Registry 에서 정의하거나 충돌 방지 네임스페이스를 포함하는 URI로 정의해야 합니다.

    - private claim : 등록되어 있지도, 공개되지도 않은 클레임입니다.

     

    시그니처(signature)

    시그니처 구조

    시그니처는 인코딩 된 헤더, 페이로드 그리고 비밀키(secret_key)를 가지고 헤더에 정의된 알고리즘으로 해싱하여 생성합니다.

    서명이 다른경우 invalid

     

    헤더와 페이로드는 암호화된 값이 아니라 base64로 인코딩 된 값이기 때문에 위 이미지처럼 누구나 확인이 가능합니다.. 그렇기 때문에 토큰을 검증하는 서명(signature)이 정말 중요하며 서명에 사용되는 secret_key를 잘 관리해야 합니다!

    (위 이미지처럼 확인해보려면 여기클릭)

     

    서버에서는 특정 알고리즘을 통해 서명(Signature)되어 생성된 문자열을 클라이언트로 전달하고 클라이언트는 이 jwt token을 가지고 있다가 api를 호출할 때 전달해주기만 하면 됩니다. 전달된 jwt token은 서버에서 decoding 하여 payload를 확인한 다음 권한을 부여하게 됩니다.

     

    jwt는 DB에 저장하는  방식이 아니기 때문에 DB리소스가 필요 없다는 장점이 있습니다! 또한 여러 서비스를 운영할 때 jwt 토큰을 사용하면 session처럼 특정 sesson DB에 접근하는 게 아니라 jwt 토큰 검증 로직을 통해 여러 서비스 간에 통신에서 권한을 쉽게 제한하고 허가할 수 있다는 장점도 있습니다.

     

    단점으로는 jwt 토큰이 탈취되었을 경우 누구나 해당 토큰의 권한을 가지고 서비스를 이용할 수 있습니다. 그리고 누구나 헤더와 페이로드의 내용을 볼 수 있기 때문에 보안에 위협이 될만한 정보나 개인정보가 있다면 노출될 수 있다는 단점도 있고요. (그래서 그런 정보는 넣으면 안 됩니다) 이러한 이유로 보통 jwt토큰의 만료시간(exp)을 짧게 정하고 리프래시 토큰(Refresh Token)과 함께 사용합니다.

    또 다른 단점으로는 토큰에 담고있는 정보가 많아질수록 데이터의 크기가 커진다는 겁니다. 그렇게 되면 네트워크 전달시 데이터의 크기로 부하가 생길 수 있습니다.

     

    리프래시 토큰은 DB에 저장되며 긴 만료시간을 가지고 있습니다. 사용자는 jwt 토큰이 만료되면 리프래시 토큰을 이용해 갱신을 하여 사용하게 됩니다. 우리가 앱에서 별도의 재로그인 없이 계속 서비스를 이용할 수 있는 것은 리프래시 토큰 덕분입니다.

     

    근데 리프래시 토큰까지 탈취되면 어떡하나요??

     

    비교적 만료시간이 짧은 jwt토큰은 탈취되어도 금방 만료되기 때문에 보안상 위협이 비. 교. 적. 적은데 반해 리프래시 토큰은 새로운 jwt 토큰을 발급받을 수 있기 때문에 탈취되면 위험합니다. 이런 경우 토큰의 payload를 확인해서 userid를 블락(block)시키는 방법과, 해당 유저의 리프래시 토큰을 모두 만료시키는 방법이 있겠습니다!

     

     

    4. 마치며


    Oauth2.0 까지 정리하고 싶었는데 너무 길어져서...ㅎㅎ 간단히 말하자면 Oauth2.0은 의미 없는 문자열 토큰으로 여러 플랫폼에 권한을 주기 위해 사용되는 기술입니다. 그리고 jwt와 Oauth2.0 은 비교하기 애매합니다!

     

    jwt는 토큰의 한 종류이고, Oauth2.0은 프레임워크라고 합니다. Oauth 2.0으로 생성하는 토큰은 위에서 말했다시피 의미없는 문자열이지만 이걸 jwt토큰으로도 생성할 수 있습니다.

     

    마치며, 서버 개발자라 보안에 대해 보안 전문가만큼 깊이 있게 알지는 못하지만 로그인을 통한 인증/인가 부분이 제일 쉽게 맞닥뜨릴 수 있는 보안에 첫 시작이라고 생각합니다. 그렇기 때문에 장단점을 알고 보안에 위협되는 행동에서 어떻게 대처해야 하는지 알고 사용하면 좋을 것 같습니다!

     

    그럼 오늘도 즐거운 코딩 하세요~

     

     

    참고

    https://lewis-kku.tistory.com/34

     

    JWT와 OAuth 차이점

    면접 대비를 위해 공부하던 중 JWT와 OAuth 를 비교하는 질문을 봤다. 찾아보니 이 둘을 비교하는 것은 흔한 질문이지만, 좋은 접근은 아니다. JWT가 과일이라면 OAuth는 과일을 담는 상자라고 볼 수

    lewis-kku.tistory.com

    spring securety jwt 사용하기

     

    spring security jwt 사용하기(access token, refresh token)

    로그인시 jwt를 사용해서 인증과정을 구현해보려고 합니다. jwt 발급 및 검증 과정을 spring의 filter 레벨에서 구현하기 위해 spring security를 사용했습니다. 그리고 jwt의 access token과 더블어 refresh token

    velog.io

    jwt 토큰을 발행해보자

     

    JWT 토큰을 발행해보자

    JWT 토큰은 JSON Web Token의 약자로 전자 서명된 URL-safe의 JSON입니다.

    velog.io

    https://brunch.co.kr/@jinyoungchoi95/1

     

    JWT(Json Web Token) 알아가기

    jwt가 생겨난 이유부터 jwt의 실제 구조까지 | 사실 꾸준히 작성하고 싶었던 글이지만 JWT를 제대로 개념을 정리하고 구현을 진행해본 적이 없었는데 리얼월드 프로젝트를 진행하면서 JWT에 대한

    brunch.co.kr

     

    댓글

운동하는 개발자 JAY-JI