분류 기타

JWT를 사용하여 REST API를 보호하는 방법

컨텐츠 정보

  • 조회 356 (작성일 )

본문

REST API는 논리적으로 간단하고 복잡한 상태를 메모리에 유지하지 않고 리소스를 처리하여 전체 비즈니스 로직을 응집력 있게 처리합니다. 

나는 그들을 정말 좋아하고 당신이 이것을 읽고 있기 때문에 당신도 그렇게 생각합니다.


즉, REST API의 특성과 메커니즘으로 인해 보안을 유지하는 것이 항상 간단한 것은 아닙니다. 사용자가 자격 증명을 제출하면 어떻게 됩니까? 고객이 후속 요청에 올바르게 로그인했는지 어떻게 알 수 있습니까? 이를 알리기 위해 서버 측에 상태를 유지할 수 없습니다. 그래서 당신은 무엇을 합니까?


이 기사에서는 이를 달성 할 수 있는 매우 강력하면서도 간단한 방법 인 JSON 웹 토큰을 사용하여 공유하고자 합니다.


https://blog.logrocket.com/how-to-secure-a-rest-api-using-jwt-7efd83e71432/


JWT 란? 


JSON 웹 토큰은 쌍방 상호 작용 중에 사용자의 신원을 안전하게 표현할 수 있는 개방형 표준 (RFC 7519) 방식입니다. 즉, 두 시스템이 데이터를 교환 할 때 JSON 웹 토큰을 사용하여 모든 요청에 ​​대해 개인 자격 증명을 보낼 필요 없이 사용자를 식별 할 수 있습니다.


이를 REST API 컨텍스트에 적용하면 클라이언트-서버 상호 작용이 이러한 메커니즘에서 어떤 이점을 얻을 수 있는지 확인할 수 있습니다.


간단히 말해서 JWT는 다음과 같이 작동합니다.


0*iS5eKdJLJvLLDsKd 



  1. 사용자 / 클라이언트 앱이 로그인 요청을 보냅니다. 즉, 사용자 이름 / 암호 (또는 제공해야 하는 다른 유형의 로그인 자격 증명)가 이동하는 곳입니다.
  2. 확인되면 API는 JSON 웹 토큰을 생성하고 (자세한 내용은 잠시 후) 비밀 키를 사용하여 서명합니다.
  3. 그런 다음 API는 해당 토큰을 클라이언트 애플리케이션에 반환합니다.
  4. 마지막으로 클라이언트 앱은 토큰을 수신하고 자체적으로 인증하여 인증되었는지 확인한 다음 더 이상 자격 증명을 보내지 않고도 사용자를 인증하기 위한 모든 후속 요청에서 계속 사용합니다.

사실이 되기에는 너무 간단하게 들리지 않습니까? 어떻게 안전해야 하나요? 좀 더 설명하겠습니다.


토큰의 구조 


API에서 반환하는 토큰 자체는 인코딩 된 문자열입니다. 점 문자로 구분 된 세 가지 섹션으로 구성됩니다.


header.payload.signature

각 섹션에는 퍼즐의 중요한 부분이 포함되어 있습니다. 디코딩 되면 처음 두 개는 관련 정보를 포함하는 데이터의 JSON 표현이고 마지막 두 개는 토큰의 진위 여부를 확인하는 데 사용됩니다.


  • The header는 처리 중인 토큰 유형 및 생성에 사용 된 알고리즘과 관련된 데이터가 포함됩니다. 여기에 몇 가지 호환 가능한 알고리즘이 지정되지만 가장 일반적인 알고리즘은 HS256 및 RS256입니다. 찾고 있는 보안 표준과 조치에 따라 달라집니다. 이 두 가지 예에서 하나는 서버와 클라이언트 모두에 알려진 비밀 키를 사용하고 다른 하나는 클라이언트가 알고 있는 공개 키와 함께 서버에서 사용하는 개인 키를 사용합니다.
  • payload에는 요청 및 요청하는 사용자와 관련된 데이터가 포함됩니다. 구현에 사용할 수 있는 JWT의 일부로 정의 된 표준 키 / 값 쌍 세트가 있습니다.
  • Iss (발급자)-즉, 요청하는 사용자를 식별하는 방법
  • Sub (subject)-또는 오히려 요청의 제목입니다. 우리의 경우에는 사용 된 URI를 포함하는 것이 좋습니다.
  • Aud (청중)-이 토큰을 받는 사람의 신분증을 제공하려고 했습니다.
  • Exp (만료일)-토큰은 일반적으로 영원히 지속되지 않습니다. 이는 토큰을 사용하는 사람이 실제로 최근에 생성 된 토큰을 제공하고 있는지 확인하기 위한 것입니다.

표준의 일부로 정의 된 페이로드 객체에 추가 할 수 있는 다른 속성이 있지만 위의 속성이 가장 일반적인 속성입니다. 물론 클라이언트와 서버가 모두 구현에 동의하는 한 이를 사용하거나 직접 정의 할 수 있습니다.


  • signature은 서버와 클라이언트가 페이로드의 신뢰성을 확인하기 위해 사용하는 인코딩 된 문자열입니다.

지금까지 우리가 다룬 모든 것을 하나의 예로 묶어 보겠습니다.


토큰 사용 


회사의 급여 API 용 클라이언트를 개발하고 있다고 가정 해 보겠습니다. 이 API는 회사 직원에게 대금을 지급하고, 직원에 대한 과거 정보를 검색하고, 마지막으로 직원 정보를 편집하기 위한 것입니다.


또한 (인적 오류를 방지하기 위해) API 개발자는 이러한 작업 중 일부에 관리자 권한이 필요하다고 결정했습니다. 따라서 정보를 검토 만 할 수 있는 일반 액세스 권한이 있는 사용자와 결제를 발행하고 데이터를 수정할 수 있는 최고 액세스 권한이 있는 사용자 (관리자)가 있습니다.


매우 기본적인 예이지만 JWT로 작업을 수행하는 이유에 대한 명확한 아이디어를 제공하는 것으로 충분합니다.


위에서 언급 했듯이 보안 API와의 모든 상호 작용은 로그인 요청으로 시작됩니다. 다음과 같이 보일 것입니다.


POST /api/users-sessions 


Payload:


{
Username”: fernando
Password”: fernando123
}

자격 증명이 유효하다고 가정하면 시스템은 새 JSON 웹 토큰을 반환합니다. 하지만 이 토큰에 대해 자세히 살펴 보겠습니다.


특히 페이로드 내부의 정보에 대해 생각해 보겠습니다. 흥미로운 옵션은 다음과 같습니다.


  • Iss– 로그인 한 사용자의 사용자 이름을 포함합니다. UI에 표시하고 싶을 수 있기 때문에 특히 유용합니다.
  • Exp –이 새 토큰은 다음 8 시간 동안 만 사용할 수 있기 때문입니다 (일반적으로 사용자가 매일 사용하는 시간).
  • Admin – 사용자의 역할을 설명하는 부울입니다. 이는 UI에 유용합니다. 일부 UI 요소를 표시할지 숨길 지 이해해야 하기 때문입니다.

간단하게 하기 위해 데이터 인코딩에 HS256 알고리즘을 사용할 것입니다. 즉, 클라이언트와 API 모두에서 동일한 비밀을 사용합니다. 이 예의 목적을 위해 우리의 비밀은 다음과 같습니다.


비밀 API 예제


이제 토큰의 다른 섹션이 어떻게 보이는지 살펴 보겠습니다.


Header: 


{
alg”: HS256”,
typ”: JWT
}

Payload: 


{
Iss”: fernando
Exp”: 1550946689,
Admin”: false
}

이제 실제 토큰을 생성하려면 위 항목을 인코딩 한 다음 결과 값에 서명하여 최종 조각을 토큰에 추가해야 합니다.


그래서 우리는 :


Base64(header) = ewoiYWxnIjogIkhTMjU2IiwKInR5cCI6ICJKV1QiCn0K
Base64(payload) = ewoiSXNzIjogImZlcm5hbmRvIiwKIkV4cCI6IDE1NTA5NDY2ODksCiJBZG1pbiI6IGZhbHNlCn0K
HS256(Base64(header) + “.” + Base64(payload), A secret API example”) = TseARzVBAtDbU8f3TEiRgsUoKYaW2SbhCWB0QlKpdp8

API가 반환하는 최종 토큰은 지금까지 짐작 하셨을 것입니다.


ewoiYWxnIjogIkhTMjU2IiwKInR5cCI6ICJKV1QiCn0K.ewoiSXNzIjogImZlcm5hbmRvIiwKIkV4cCI6IDE1NTA5NDY2ODksCiJBZG1pbiI6IGZhbHNlCn0K.TseARzVBAtDbU8f3TEiRgsUoKYaW2SbhCWB0QlKpdp8

여기에 흥미로운 부분이 있습니다. 이것이 왜 그렇게 강력한 지 보여 드리겠습니다.


이 토큰을 받으면 클라이언트 애플리케이션은이를 해독하고 헤더와 페이로드 부분을 잡아서 자체적으로 서명하여 유효성을 검사 할 수 있습니다 (물론 클라이언트와 서버가 모두 비밀 문구를 알고 있기 때문에 가능합니다). 이렇게 하면 아무도 메시지 내용을 변경하지 않고 안전하게 사용할 수 있습니다.


동시에 클라이언트 앱에서 보낸 추가 요청에는 이 동일한 토큰이 포함되며,이 토큰은 매번 다시 서명하고 결과를 토큰의 서명 부분과 비교하여 서버에서 유효성을 검사합니다.


예를 들어, 누군가가 메시지의 페이로드에 간섭하고 "admin"속성을 "true"로 변경하여 가짜 (또는 유효한 비 관리자 사용자)가 권한 있는 작업 (예 : 특정 직원).


이러한 작업은 페이로드 콘텐츠를 다음과 같이 수정합니다.


ewoiSXNzIjogImZlcm5hbmRvIiwKIkV4cCI6IDE1NTA5NDY2ODksCiJBZG1pbiI6IHRydWUKfQo=

클라이언트 앱에서 보낸 최종 토큰은 다음과 같습니다.


eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.ewoiSXNzIjogImZlcm5hbmRvIiwKIkV4cCI6IDE1NTA5NDY2ODksCiJBZG1pbiI6IHRydWUKfQo=.TseARzVBAtDbU8f3TEiRgsUoKYaW2SbhCWB0QlKpdp8

그리고 이 토큰의 서명은 다음과 같아야 합니다.


doRnK7CoVjFOiFmvrQ2wvxcGeQuCYjzUchayNAYx1jw

메시지의 일부로 전송 된 것과 일치하지 않으므로 요청이 변조 되었음을 증명합니다.


200 개의 유일한 모니터 실패 및 프로덕션에서 네트워크 요청 속도 저하 


JWT를 사용하여 REST API를 보호하는 것이 중요하지만 API가 프로덕션에서 앱에 계속 리소스를 제공하는지 확인하는 것이 문제가 되는 부분입니다. 백엔드 또는 타사 서비스에 대한 요청이 성공적인지 확인하려면 LogRocket을 사용해보세요.


LogRocket Dashboard Free Trial Banner 


LogRocket은 말 그대로 사이트에서 일어나는 모든 일을 기록하는 웹 앱용 DVR과 같습니다. 문제가 발생하는 이유를 추측하는 대신 문제가 있는 네트워크 요청을 집계하고 보고하여 근본 원인을 신속하게 이해할 수 있습니다.


LogRocket은 페이지로드 시간, 첫 번째 바이트까지의 시간, 느린 네트워크 요청과 같은 기본 성능 타이밍을 기록하고 Redux, NgRx를 기록하도록 앱을 계측합니다. 및 Vuex 작업 / 상태. 무료로 모니터링을 시작하십시오.


마지막 생각들 


지금까지 JWT 보안에 수반되는 기본 사항을 파악하고 REST API를 보호하는 것이 실제로 그렇게 어렵지 않다는 것을 깨달았기를 바랍니다. 물론 내가 이 기사에서 언급하고 보여준 것에 대한 변형이 있지만 jwt.io를 방문하여 직접 확인할 수 있습니다. 해당 사이트에서 JSON 웹 토큰을 생성하고 검증 할 수 있을 뿐만 아니라 가장 일반적인 프로그래밍 언어에 대한 기본 JWT 라이브러리에 대한 링크도 제공됩니다.


기본적으로 API에 JWT 보안을 추가하는 작업을 시작하는 데 필요한 모든 것은 이미 웹 사이트를 통해 쉽게 액세스 할 수 있습니다.


마지막 경고로 여기에서 다룬 메커니즘은 매우 간단하고 모든 사람이 액세스 할 수 있지만 API에 JWT 보안을 추가하는 것만으로는 충분하지 않다는 점을 이해해야 합니다. 위의 작업을 수행하면 방탄이 될 수 없으며 많은 스마트 해커가 그 주위를 찾을 수 있습니다. 여전히 당신을 해칠 수 있는 (그리고 그렇게 될) 많은 다른 공격들이 있습니다. 보안은 하나의 일반적인 보안 체계를 구현하는 것이 아니라 모든 전선을 덮는 것입니다. 항상 JWT와 함께 사용되는 추가 보호 계층은 HTTPS 연결로 모든 네트워크 트래픽을 보호하는 것입니다. 즉, 사용자가 보내고 받는 모든 것이 포트 443 (또는 사용 중인 사용자 지정 번호)을 통과해야 하며 오래되고 안전하지 않은 포트 80이 아닌지 확인하십시오.


그리고 그게 다야! 이 주제의 중요한 측면을 언급하는 것을 잊었다 고 느끼거나 흥미롭고 도움이 되었다고 생각되면 언제든지 연락하여 의견을 남기십시오. 또한 여러분의 의견을 듣고 싶습니다.


다음 것까지!


LogRocket : 웹 앱에 대한 완전한 가시성 


LogRocket Dashboard Free Trial Banner 


LogRocket은 마치 자신의 브라우저에서 발생한 것처럼 문제를 재생할 수 있는 프런트 엔드 애플리케이션 모니터링 솔루션입니다. 오류가 발생한 이유를 추측하거나 사용자에게 스크린 샷 및 로그 덤프를 요청하는 대신 LogRocket을 사용하면 세션을 재생하여 무엇이 잘못되었는지 빠르게 이해할 수 있습니다. 프레임 워크에 관계없이 모든 앱에서 완벽하게 작동하며 Redux, Vuex 및 @ ngrx / store에서 추가 컨텍스트를 기록하는 플러그인이 있습니다.


Redux 작업 및 상태 로깅 외에도 LogRocket은 콘솔 로그, JavaScript 오류, 스택 추적, 헤더 + 본문이 포함 된 네트워크 요청 / 응답, 브라우저 메타 데이터 및 사용자 지정 로그를 기록합니다. 또한 페이지에 HTML 및 CSS를 기록하는 DOM을 계측하여 가장 복잡한 단일 페이지 앱의 픽셀 단위까지 완벽한 비디오를 재현합니다.



JWT