JWT와 OAuth

byeol·2023년 4월 7일
0

JWT = 과일🍎 = Token의 한 형식

OAuth = 과일을 담는 상자📦 = 하나의 Framework

🍎 Token 기반 인증 방식

JWT는 인증에 필요한 정보들을 암호화시킨 토큰을 의미합니다.
세션/쿠키 방식과 유사하게 사용자는 Access Token(JWT Token)을 HTTP 헤더
에 실어 서버에 전송합니다. 토큰은 임의의 생성된 비밀번호와 같이 동작합니다.
제한된 수명을 가지고, 새로운 토큰은 한번 만료되면 새로 생성해야 합니다.

Header + Payload + Verigy Signature
Header : 암호 방식, 타입
Payload : 서버에 보낼 데이터 ex) userId, 유효기간
VerifySignature : Base64 방식으로 인코딩한 Header, Payload, Secret key를 더한 후 서명

💡Payload 에 유저의 중요한 정보(비밀번호 등) 가 들어가면 쉽게 노출

인증절차

  1. 사용자가 로그인을 합니다.
  2. 서버에서 계정 정보를 읽어 사용자를 확인 후, 사용자의 고유 ID 값을 부여한 후 기타 정보와 함께 Payload에 집어넣습니다.
  3. JWT 토큰의 유효기간을 설정합니다.
  4. 암호화할 Secret key를 이용해서 AccessToken을 발급합니다.
  5. 사용자는 Access Token을 받아 저장 후 , 인증이 필요한 요청마다 토큰을
    헤더에 실어 보냅니다.
  6. 서버에서는 해당 토큰의 Verify Signature를 Secret key로 복호화한 후, 조작
    여부, 유효 기간을 확인합니다.
  7. 검증이 완료되었을 경우, Payload를 디코딩하여 사용자의 ID에 맞는 데이터를 가져옵니다.

세션/쿠키 방식과의 가장 큰 차이점

세션/쿠키는 세션 저장소에 유저 정보를 넣는 반면
JWT는 토큰 안에 유저의 정보들이 넣어진다.
클라이언트 입장에서는 HTTP 헤더에 세션ID나 토큰을 실어서 보낸준다는 점에서 동일 서버 측에서는 인증을 위해 암호화를 한다 vs. 별도의 저장소를 이용한다의 차이

장점

  • 간편하다
    세션/쿠키 인증은 별도의 저장소 관리가 필요
    JWT는 발급한 후 검증만 하면 되기 때문에 별도의 저장소가 필요하지 않음
    이는 서버를 확장하거나 유지, 보수하는데 유리
  • 확장성이 뛰어나다.
    토큰 기반으로 하는 다른 인증 시스템에 접근이 가능하다.
    Facebook, Google, Microsoft 로그인 등은 모두 토큰 기반으로 인증을 하는데
    권한을 받을 수도 프로필을 써드파티 웹사이트에 제공하도록 허가할 수도 있다.

단점

  • 이미 발급관 JWT에 대해서는 유효기간이 완료될 때까지 계속 사용 가능
    세션/쿠키는 서버에서 강제로 삭제할 수 있다. 그러나 JWT는 유효기간이 지나기
    전까지 정보들을 이용할 수 있다.
    이에 대한 해결책으로 Access Token 유효기간을 짧게 하고 Refresh Token
    이라는 새로운 토큰을 발급
  • Payload 정보가 제한적
    Payload는 암호화되지 않아서 디코딩하면 누구나 정보를 확인 가능
    따라서 유저의 중요한 정보를 Payload에 넣지 못함
  • JWT 길이
    JWT의 길이는 길기 때문에 인증이 필요한 요청이 많아질 수록 서버의
    자원 낭비가 발생

📦OAuth

OAuth는 인터넷 사용자들이 비밀번호를 제공하지 않고
다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나
애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단
으로서 사용되는, 접근 위임을 위한 개방형 표준이다. (위키백과)

OAuth 2.0은 외부 서비스(third-party application)의 인증 및 권한부여를
관리하는 범용 프레임워크 입니다.
OAuth 기반 서비스의 API를 호출을 할 때에는,
HTTP 헤더에 access token을 포함하여 요청을 보내게 됩니다.
서비스는 access token을 검사하면서 이 요청이 유효한지 판단하여
적절한 결과를 응답합니다.

OAuth 구성하는 4가지 주요 객체

  • Resource Server : Client가 제어하고자 하는 자원을 보유하고 있는 서버
    access token을 사용해서 요청을 수신할 때, 권한을 검증한 후 적절한 결과를 응답
    ex) Fackbooek , Google, Twitter
  • Authorization Server : 권한 서버. 인증/인가를 수행하는 서버로 클라이언트의
    접근 자격을 확인하고 Access Token을 발급하여 권한을 부여하는 역할
    Resource Server를 2개로 나눠 데이터를 가진 서버와 인증을 담당하는 서버로 보기도 한다.
  • Resource Owner : 자원의 소유자
    ex) Client가 제공하는 서비스를 통해 로그인하는 실제 유저
  • Client : Resource Server에 접속해서 정보를 가져오고자 하는 클라이언트
    ex) 웹 어플리케이션

OAuth Flow

1. Client 등록
Resource Server를 이용하기 위해서 자신의 서비스를 등록함으로써
사전 승인을 받아야한다. ex) Developer Settings
등록하면 3가지의 정보를 부여 받는다.

    1. Client ID : 클라이언트 웹 어플리케이션을 구별할 수 있는 식별자
      노출해도 무방
    1. Client Secret : Client ID에 대한 비밀키로서, 절대 노출 ❌
    1. Authorized redirect URL : Authorized Code를 전달받을 리다이렉트 주소
      = 사용자의 인증이 성공했을 경우 콜백함수로 리다이렉트할 주소이다

      Google 등 외부 서비스를 통해 인증을 마치면 클라이언트를 명시된 주소로 리다이렉트 시킨다
      이 때 Query String으로 특별한 Code가 함께 전달된다.
      클라이언트는 해당 Code와 ClientID, Client Secret을 Resource Server에
      보내 Resource Server의 자원을 사용할 수 있는 Access Token을 발급받는다.
      등록되지 않은 리다이렉트 URL을 사용하는 경우 Resource Server가 인증을 거부

      사용자 로그인 -> resource server에서 인증 마치면 resource server는 리다이렉트 URL/code?내용으로 코드값 보냄
      -> Client는 url에서 쿼리를 통해서 코드 값을 얻고 코드값 + client ID + Client Secret을 Resource Server에 보냄
      -> Resource Server는 Access Token을 Client에 준다.

2. Resource Owner의 승인 (사용자)

프론트(Client)에서 네이버 로그인 버튼에

https://nid.naver.com/oauth2.0/authorize?**response_type**=code&**client_id**=Vr0VLhUtPT00W8PYss0h&**state**=ZXpNAd7CzQSJ9TW7qNUyBSgkYCUFfi53q05W9wn9yg%3D&**redirect_uri**=https://api.okky.kr/login/oauth2/code/naver
uri 를 만든다.

위 예시는 okky의 로그인 화면인데

Naver 로그인을 누르면

https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id**=Vr0VLhUtPT00W8PYss0h&state=ZXpNAd7CzQSJ9TW7qNUyBSgkYCUFfi53q05W9wn9yg%3D&redirect_uri=https://api.okky.kr/login/oauth2/code/naver

와 같은 링크로 연결된다!

Resource Owner가 그 버튼을 누르면 위에서 만들었던 uri 링크로 접속하여요청을 보낸다.

Resource Server는 로그인 화면을 보여준다.

Resource Owner는 ID와 PW를 입력하고 로그인 버튼을 누르면!

Resource Server는 Owner가 요청했던 URL에서 Client id와 자신이 가지고 있는 Client id를 비교한다. 요청에 들어왔던 redirect_uri와 자신이 가지고 있던 redirect_uri가 같은지도 확인한다.

https://nid.naver.com/oauth2.0/authorize?response_type=code&client_id**=Vr0VLhUtPT00W8PYss0h&state=ZXpNAd7CzQSJ9TW7qNUyBSgkYCUFfi53q05W9wn9yg%3D&redirect_uri=https://api.okky.kr/login/oauth2/code/naver

비교하여 일치한다면 Resource Owner에게 scope(scope는 어떤 기능에 대한 범위로 예를 들어 구글의 캘린더 기능 등과 같은)에 대한 정보를 허용할 것인지를 선택하는 화면을 보낸다!

Resource Owner가 허용한다면 Resource Server가 가지고 있는 최종값은 아래와 같다.

Resource Server
* Client id : 1
* Client : 2
* redirect URL : `https://client/callback`
* user id : 1
* scope : 구글의 캘린더 기능

3.Resource Server의 승인

Resource Server는 여기서 accessToken을 바로 만드는 것이 아니라,

임시 비밀번호인 authorization code를 만든다.

Resource Server
* Client id : 1
* Client : 2
* redirect URL : `https://client/callback`
* user id : 1
* scope : A, B
* authorization code: 3

그리고 Resource Owner에게 특정 주소로의 리다이렉트 요청을 보내도록 한다.

https://client/callback?code=3

그러면 Client는 저기 쿼리 스트링에 있는 코드인

authorization code:3 값을 저장한다.

이제 Client는 Resource Server에게 아래 요청을 보낸다.

https://resource.server/token?grant_type=authorization_code&code=3
&redirect_uri=https://client/callback&client_id=1&client_secret=2

Resource Server는 자기가 가진 정보와 위 요청 정보가 같다면

authorization code를 지우고 accessToken을 발급하여 Client에게 전송한다.

Client도 authorization code를 지우고 accessToken을 가지게 된다.

Client
* Client id : 1
* Client : 2
* accessToken: 4

reference

https://tofusand-dev.tistory.com/89
https://tecoble.techcourse.co.kr/post/2021-07-10-understanding-oauth/
https://wordbe.tistory.com/entry/OAuth-20-%EC%84%A4%EB%AA%85

profile
꾸준하게 Ready, Set, Go!

0개의 댓글

관련 채용 정보