본문 바로가기
Knowledge/- Security

jwt, oauth 2.0, OpenID Connect 공부

by Yoojacha 2022. 10. 3.

로그인 상태를 유지하기 위해서 jwt의 만료에 따라 refresh token을 해주어야 한다는 것을 알게 되었다.

 

passport google strategy를 보니 access token 과 refresh token을 전혀 사용안했었는데 있었던 이유를 알게 되었다.

그래서 자세히 정리해보려 한다.


  • request는 stateless이기 때문에 서버는 누가 요청을 보내는지 모르기 때문에 세션DB에 user_id가 저장되어 있는 세션ID가 담긴 쿠키를 클라이언트에게 발급한다.
  • 서버는 쿠키가 들어오는 것을 확인해 세션ID를 deserialize 후 서버는 user_id가 무엇인지 알아낸다.
  • 서버는 user_id를 가지고 요청을 처리후 응답을 한다.
  • 쿠키는 그저 세션 ID를 전달하기 위한 수단(매개체)일 뿐이다.
  • 쿠키는 브라우저에만 있는 기능이다. 그래서 네이티브 앱에서는 불가능!
  • 모든 요청이 올 때마다 세션id를 통해 deserialize한 user_id를 verify 하려면 항상 DB조회를 해야한다
    -> DB 사용이 과도해진다
    -> JWT 를 사용하면 세션 DB가 필요없다. 서버의 일이 줄어든다.

JWT (Jsonwebtoken)

  • 토큰의 의미 = 신분증처럼 클라이언트가 서버에게 보여주는 것을 의미
  • JWT의 의미 = 정보를 가지고 있는 토큰 ( 형태: header.payload.signature )
  • 토큰이 만료될 때까지 서버가 클라이언트를 강제할 수 있는 방법은 없다.
  • 서버는 토큰 쿠키에 저장을 했을 때 토큰을 refresh 해서 재발급해주거나, 삭제만 가능하다.
  • 토큰을 localStorage에 저장을 한다면 안드로이드, ios에서도 사용 가능하다.
  • DB 리소스를 줄일 수 있다.
  • QR코드로 인코딩이 가능해 사용방법이 다양하다.
  • 보안 문제가 생긴다면 모든 JWT의 SECRET_KEY를 바꾸면 된다.
  • Signature와 Payload에는 HMACSHA256 algorithm 사용 / header에는 Base64URL 사용으로 암호화 되지 않았다.
  • JWT를 암호화하고 싶다면 JSON Web Encryption (JWE)를 고려해보자.
  • Header 에서 signning 알고리즘 종류를 선택할 수 있다. ( 지원하는 라이브러리일 경우 )
  • 쿠키에 저장하면 XSRF( Cross-Site Request Forgery ) 공격이 문제가 될 수 있다.
    -> localStorage에 저장해야한다.
    -> localStorage에 저장하면 XSS 공격에 안전하다. 왜냐하면 sanitizing 해주는 프레임워크들이 많기 때문이다.
  • 보안을 높이려면 만료시간을 짧게 잡고, 토큰 재발급을 자주 해준다.

oauth 2.0 생활코딩 정리

  • accessToken를 서버가 획득
  • Resource Owner - Client - Resource Server (API, Identity Provider[idp])
    (예를들어 구글이 두 개의 레이어를 가지고 있지만 Resource Server 한 개로 생략한 상태로 설명함)
  • 권한을 부여하는 과정에서 인증이 끝나면 redirect_uri를 cilent에게 준다. 준다. callback
  • scope의 경우 resouce server에서 필요한 기능을 정해주는 역할을 한다.
  • 서버가 client_id 와 client_scret을 Resource Server에게 주어야 한다.
  • Resource Owner는 로그인 요청을 보내 인증이 성공하면 Resource Server가 authorization code를 Resource Owner에게 응답해주면서 임시적으로 authorization code를 들고 있는다.
  • 다시 Resource Owner가 authorization code를 Client가 받아 client_id와 client_scret을 함께 Resource Server에게 보낸다.
  • 3 가지를 다 받은 Resource Server는 authorization code를 확인 후 지우고, 새로 accessTokenrefreshToken을 client 에게 발급한다. (이 때 scope에 따라서 어떤 자원을 읽도록 허용할 지 정해준다.)
  • accessToken은 수명이 있다. (accessToken을 쉽게 발급할 수 있도록 refreshToken을 사용한다.)

 

 

nodejs의 passport에서 accessToken과 refreshToken을 사용하는 방법은 찾아보지만 아직 좋은 글을 발견하지 못했다..


 

OpenID Connect

  • OIDC 라고도 부른다.
  • 사용자 인증에 사용되는 개방형 표준이다.
  • OAuth 2.0 기술을 이용하여 만들어진 인증 레이어이다.
  • OpenID Connect는 OAuth 2.0 기능을 확장한다.
  • 키 대신해 클라이언트(애플리케이션)에게 내가 누구인지 기본 정보를 제공해주는 특정 권한을 가지는 뱃지를 준다.
  • ATM 기기가 비슷한 체계를 가지고 있다. 카드에 정보가 담겨 있다.
  • Oauth 프레임워크 위에서 작동한다. (Oauth가 없이는 작동하지 않는다.)
  • ID token을 발급해서 Resource Server와 Client 둘다 가지고 있는다. (ID token과 accessToken은 매우 다르다.
  • JWT로 이루져서 Client가 디코딩해서 JWT 안의 정보를 알 수 있다.
  • OAuth 2.0를 사용할 때 Bearer 토큰을 사용하지만 OpenID Connect의 경우 ID 토큰을 쓸 수 있다.
  • ID Token(JWT) 안에는 인증 이벤트와 사용자에 대한 청구가 포함된다.
  • accesstoken을 발급해주는 방식과 다르게 ID token을 발급하면 발급하는 횟수를 줄여줄 수 있다.

  • SAML 2.0 : 2001년 OASIS에서 정의한 개방형 Authentication(인증) 및 Authorization(인가) 표준이며, 엔터프라이즈 애플리케이션의 SSO(Single Sign On)를 목적으로 XML(Extensible Markup Language) 형식으로 개발
  • OAuth 2.0 : 2006년 Twitter와 Google이 정의한 개방형 Authorization 표준이며, API 허가를 목적으로 JSON(Javascript Object Notation) 형식으로 개발
  • OIDC 2.0 : 2014년 OpenID Foundation에서 정의한 개방형 Authentication 표준이며, 컨슈머 어플리케이션의 SSO를 목적으로 JSON 형식으로 개발

https://www.samsungsds.com/kr/insights/oidc.html


https://www.youtube.com/watch?v=hm2r6LtUbk8&list=PLXB5p_g4hZpMgHGZ4iMefHl_6D51sEhaT 

 

 

댓글