지난 봄,사용자들은 Toolz.dev 에서 로그아웃하기 시작했습니다. 가끔은 아닙니다 - 끊임없이. 로그인하고,하나의 도구를 클릭하고,붐: 로그인 화면으로 돌아갑니다. 백엔드는 15 분 액세스 토큰과 7 일 새로 고침 토큰을 발행하고,I'd 는 그 흐름을 백 번 테스트했습니다. 그래서 자연스럽게 새로 고침 엔드 포인트가 깨졌다고 가정하고,아무 문제가 없는 Express 미들웨어를 읽는 데 1 시간 40 분을 소비했습니다.
그리고 나서 마침내 당연한 일을 했습니다. Authorization 헤더에서 라이브 액세스 토큰을 꺼내 디코더에 붙여넣고 클레임을 살펴보았습니다. The exp 괜찮았어요. 그만큼 iat 괜찮 았어. 토큰은 또 다른 14 분 동안 유효했다. 이는 서버가 괜찮 았음을 의미 - 그리고 버그는 클라이언트에 있어야했다. 충분히 확실: 내 프론트 엔드가 확인하고 있었다 payload.exp < Date.now(). exp 시대 이후 몇 초입니다. Date.now() 밀리초입니다. 새로 발행된 모든 토큰은 1970 년쯤 어딘가에서 만료된 것처럼 보였으므로 클라이언트 "helpfully" 서버가 발언권을 갖기 전에 모든 사람을 로그아웃했습니다. 수정의 세 문자 - /1000- 거의 2시간의 사냥 끝에.
That's 당신의 연장통에 있는 JWT 암호해독기를 비치하고 있는을 위한 전체적인 피치. JWT 는 선 소음 같이 봅니다 - 점으로 함께 접착되는 base64url 횡설수설의 3 개의 덩어리 - 그러나 it's 다만 트렌치 코트를 착용하는 JSON. 당신이 주장을 읽을 수 있는 순간,당신의 auth 벌레의 반은 신비인 중지합니다. 틀린 경청자,만료된 토큰,잃어버린 역할,시계 기울기,밀리초-vs-초 - they're 모두는 당신이 암호해독하는 때 보통 원본에서 바로 거기 앉습니다.
그러나 - 그리고 이것은 중요합니다 - 당신이 해독하는 곳은 중립적 인 선택이 아닙니다. 실제 액세스 토큰은 라이브 자격 증명입니다. 서버에 토큰을 발송하는 디코더 사이트에 붙여 넣으면 you & # 39;ve 가 방금 API 의 작업 키를 stranger & # 39;s 요청 로그에 입금했습니다. That & # 39;s 내가 구축 한 구체적인 이유 Toolz.dev JWT 디코더 브라우저에서 완전히 실행하려면. 그 이상은 아래에.
TL;DR: JWT를 온라인으로 디코딩하려면 해당 JWT를 붙여넣으세요 Toolz.dev JWT 디코더- 헤더, 페이로드, 서명을 즉시 분할하고 번역합니다
exp/iat인간의 날짜로,그리고 실행 100% 클라이언트 측 그래서 토큰은 기계를 떠나지 않습니다. 메모리에 구울 한 가지: 디코딩은 확인하지 않습니다. JWT 는 단지 base64url 인코딩 된 JSON 누구나 읽을 수 있습니다 - 키와 서명 확인 만이 그것을 증명's 신뢰할 수.
주요 특징
인스턴트 헤더, 페이로드 및 서명 분할
토큰을 붙여넣으면 디코더는 즉시 이를 세 부분으로 나눕니다: 헤더(알고리즘 및 토큰 유형), 페이로드(귀하의 주장) 및 서명(왼쪽 인코딩, it's 원시 MAC 또는 서명 - there's 아무것도 사람이 읽을 수 없기 때문에) 제출 버튼이 없고 페이지를 다시 로드할 수 없습니다. 이는 인증 라이브러리가 검증 전에 내부적으로 수행하는 작업을 정확하게 반영합니다: 분할 .는,base64url-처음 두 세그먼트를 디코딩,JSON 으로 구문 분석. 나란히 배치 된 부분을 보는 것은 형식에 대한 직관을 구축하는 가장 빠른 방법입니다. 몇 다스 토큰 후,you'll 한 눈에 RS256 라라벨 토큰 대 RS256 Auth0 토큰을 인식하기 시작 - 헤더는 매번 그것을 멀리 제공합니다.
사람이 읽을 수 있는 exp, iat 및 nbf 타임스탬프
가장 유용한 단일 기능, 전체 중지. exp, iat, 그리고 nbf numericdate 값은 Unix 시대 이후 몇 초 동안이며 나를 포함한 누구도 읽을 수 없습니다 1783430700 그리고 that's 다음 화요일 또는 우주의 열 죽음 여부를 알려줍니다. 디코더는 모든 타임스탬프 주장을 실제 날짜와 시간으로 변환합니다. 로컬 시간대와 UTC 에서. 여기서 고전적인 밀리초-대-초 버그가 즉시 표시됩니다: 디코딩된 경우 exp 56,000년 날짜로 렌더링하면 누군가가 JavaScript를 채웠습니다 Date.now() 초를 예상하는 분야로. I've 는 그 버그를 발송했습니다. 터무니없는 날짜를 보는 것은 진단입니다. 더 깊은 타임스탬프 고고학을 위해,the 타임스탬프 변환기 탭이 하나 떨어져 있습니다.
만료 카운트다운 및 상태
단지 날짜를 렌더링하는 것 이상으로,디코더는 token's 현재 상태를 알려줍니다: 유효하거나,만료되었거나, 아직 활성화되지 않은 경우 (언제 nbf 미래에 있습니다. token's 가 아직 살아 있으면 만료까지 카운트다운을 받습니다. 이것은 you're 디버깅 간헐적 401 까지 작은 편의처럼 들리며 "re debugging an intermittent 401 and need to answer "was this specific token dead when the request fired?" over and over. 카운트다운을 서버와 비교하면's configured TTL 도 잘못된 구성을 빠르게 포착합니다 - 액세스 토큰이 15 분 동안 지속되어야 하고 카운트다운에서 6 일이 적혀 있으면 발급 코드가 잘못된 config 값을 읽고 있는 것입니다.
알고리즘 및 헤더 검사
디코딩된 헤더가 표시됩니다 alg 그리고 typ (더하기 kid 그리고 친구가있을 때), 이는 단지 디버깅이 아니라 보안에 중요한 질문에 대답합니다. 이 토큰은 HS256 또는 RS256 입니까? 는 kid 당신의 JWKS 엔드 포인트가 실제로 봉사하는 열쇠를 일치하십시오? 그리고 큰 것: 입니다 alg 절대 있어서는 안되는 것, 마치 none? 토큰 주장 "alg": "none" 테스트 픽스처이거나 누군가가 검증자를 조사하고 있습니다. 어느 쪽이든 즉시 확인하고 싶을 것입니다. 단일 주장을 읽기 전에 익숙하지 않은 모든 토큰에서 먼저 헤더를 확인합니다.
구문 강조, 형식화된 JSON 청구
원시 디코딩 페이로드가 단일 라인 JSON blobs 이며,아이덴티티 제공자는 그들을 포장 사랑: 중첩 된 개체,네임스페이스 사용자 정의 주장,범위의 배열. 디코더는 꽤-구문 강조와 함께 모든 것을 인쇄 그래서 roles, scope, aud 배열,그리고 중첩된 권한 객체는 실제로 스캔이 가능합니다. It's same treatment the JSON 포맷터 귀하의 주장에 자동으로 적용되는 임의의 JSON 을 제공합니다. 두 개의 토큰을 비교할 때 - 예를 들어 엔드 포인트에 액세스 할 수있는 사용자로부터 하나와 can & # 39;t - 형식의 출력은 눈을 가늘게 뜨는 운동을 10 초의 차이로 바꿉니다.
100% 클라이언트 측 - 토큰이 브라우저에서 절대 벗어나지 않습니다
이것은 기능 I'd 싸움에 대 한. 붙여넣은 액세스 토큰은 샘플 데이터 되지 않습니다-it's 실제 사용자로 인증 하는 라이브 자격 증명 때까지 exp니다. 백엔드에 토큰을 POST 하는 모든 디코더는 서버 로그,분석, 어쩌면 타사 오류 추적기에 작업 키를 방금 작성했습니다. Toolz.dev 디코더는 자바 스크립트에서 모든 디코딩을 수행,당신의 탭에서 아무것도 전송되지 않습니다,아무것도 저장되지 않습니다. Don't 는 그것을 위해 내 말을 가져 가라: DevTools 를 열고,네트워크 탭을보고,토큰을 붙여 넣습니다. 제로 요청. 나는이 아키텍처가 모든 민감한 입력 도구에 대해 왜 중요한지 썼습니다 온라인 도구의 데이터 개인 정보 보호에 관한 나의 글입니다.
모든 스택에서 모든 JWT와 함께 작동합니다
JWT는 표준입니다 - RFC 7519- 그래서 디코더는 does't 는 누가 당신의 것을 주조했는지 신경 쓴다. Auth0 와 Firebase 토큰은 그들의 namespaced 사용자 정의 주장,Laravel Sanctum 인접 설정,Keycloak, Supabase,AWS Cognito,또는 손으로 굴린 HS256 토큰은 Toolz.dev 에 대한 내 자신의 익스프레스 백엔드 기호 - it's 점으로 연결된 세 개의 base64url 세그먼트를 포함,그것은 디코딩. 그것은 잘못된 형태의 거의 JWT 를 포함한다: 세그먼트 두 won't 가 JSON 으로 구문 분석하면 디코더는 그 자체로 진단 인 침묵 실패 대신 깨진 부분을 알려줍니다. 잘린 - 온 - 복사 토큰은 당신보다 더 일반적입니다'd 생각.
JWT 디코더 사용 방법
1단계: 토큰을 가져옵니다
앱이 보관하는 곳 어디에서나 토큰을 찾으세요. 가장 일반적으로: DevTools → 네트워크 탭 → 요청을 클릭 → 복사 Authorization: Bearer eyJ... 헤더 값 (단어 "Bearer" 없이). 또는 응용 프로그램 → 로컬 스토리지 / 쿠키를 확인,앱의 많음이 거기에 토큰을 숨겨 이후. 백엔드에서,그것을 기록하거나 테스트 제품군에서 그것을 전체 문자열을 복사 - 그것의 마지막 몇 문자를 잃는 JWT 는 여전히 디코딩하지만 결코 확인하지 않습니다,그리고 that's 당신이 don't 필요 혼란 시간.
2단계: 붙여넣기
열다 JWT 디코더 그리고 붙여넣기. 디코딩은 입력으로 발생-버튼 없음. 만약 당신이're 어디서 나 생산 토큰을 붙여 넣기에 대 한 긴장 (좋은 본능), 네트워크 탭을 먼저 열고 아무것도 전송 확인. 그것은 isn't. 그 편집증 확인 십초 걸립니다 그리고 it's 정확히 무엇 I'd 다른 사람에 게 할's 도구.
3단계: 세 부분을 읽어보세요
헤더 먼저: 확인 alg 는 시스템이 기대하는 것과 typ 이다 JWT. 그런 다음 페이로드: iss (누가 주조했는지), aud (누구를 위한 것인가's), sub (어떤 사용자), 플러스 어떤 역할, 범위, 또는 사용자 정의 주장 스택 추가. 서명은 인코딩 유지 - it's 암호화 출력, 하지 데이터. 헤더가 말하는 경우 none를, 멈추고 가서 확인자's 허용-목록을 다른 어떤 것보다 먼저 확인하십시오.
4단계: exp와 물어뜯는 주장을 확인하세요
디코딩된 것을 보세요 exp 날짜와 만료 상태. 만료? There's your 401. 유효하지만 어쨌든 거부? 이제 비교 aud 그리고 iss against your verifier's config - mismatches 만료 후 두 번째로 가장 일반적인 원인이 있습니다. 그리고 만약 어떤 타임스탬프가 다섯 자리 연도로 렌더링된다면,축하합니다: you've found a milliseconds-vs-seconds bug,그리고 나는 이로써 아주 큰 클럽에 오신 것을 환영합니다.
What's 실제로 JWT 내부? 세 부분의 해부학
RFC 7519 에 정의된 JSON 웹 토큰은 기간별로 결합된 세 개의 base64url 인코딩 세그먼트입니다: header.payload.signature. (엄격히, 서명된 다양성은 RFC 7515 당 JWS입니다 - there's 암호화된 사촌, JWE이지만, 야생에서 만날 거의 모든 토큰 you'll은 서명된 JWS입니다.)
핵심 단어는 인코딩되었습니다. Base64url 는 전송 인코딩입니다 - 바이트 URL 을 안전하게 만드는 가역적 인 방법 - 암호화가 아닙니다. JWT 를 보유한 사람은 헤더의 모든 것을 읽을 수 있으며 페이로드가 제로 키,제로 비밀,제로 노력에서 원시 인코딩으로 재생합니다 Base64 변환기 그리고 you'll see it's 표준 알파벳 with + 그리고 / 로 교환되었습니다 - 그리고 _, 패딩이 떨어졌습니다. 인코딩 자체에 대해 더 많이 썼습니다 Base64 인코딩 가이드.
일반적인 헤더를 디코딩하면 다음을 얻습니다:
{ "alg": "HS256", "typ": "JWT" }
그리고 등록된 청구항 RFC 7519로부터 구축된 페이로드는 다음을 정의합니다:
{
"iss": "https://toolz.dev",
"sub": "user_8f3a2c",
"aud": "toolz-api",
"exp": 1783431600,
"nbf": 1783430700,
"iat": 1783430700,
"jti": "b4d1f0e2"
}
iss 는 발행자, sub 주제 (일반적으로 사용자 ID), aud 대상 청중, jti 고유 토큰 ID. exp, nbf, 그리고 iat numericdate 값은 다음과 같습니다: 초 유닉스 시대 이후로. 밀리초가 아닙니다. JavaScript's Date.now() 밀리초를 반환하고 두 가지를 혼동하면 즉시 만료되는 토큰(내 Toolz.dev 로그아웃 버그) 또는 토큰이 생성됩니다 exp 사실상 만료되지 않는 56,000년의 날짜는 조용히 더 위험한 실패입니다.
HS256 대 RS256. HS256 은 공유된 비밀에 대해 HMAC와 서명합니다 - 빠르고 간단하지만 토큰을 확인하는 모든 서비스도 비밀을 보유하고 있으며 비밀을 보유한 사람은 누구나 할 수 있습니다 민트 토큰. 내 백엔드와 같은 모노리스에 적합하며 발행자와 검증자는 동일한 프로세스입니다. RS256 은 개인 키로 서명하고 공개 키로 확인하므로 공개 키를 게시하고 (JWKS 를 통해) 12 개의 마이크로서비스가 위조 할 수없이 검증 할 수 있습니다. 분산 시스템 및 타사 IdP 는 RS256 또는 ECDSA/EdDSA 형제에 있어야합니다.
X-1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X 1000 X alg: none 공격. RFC 7519는 보안되지 않은 JWT를 허용합니다 alg 이다 none 그리고 서명은 비어있습니다. 초기 라이브러리들은 header's 를 신뢰했습니다 alg 맹목적으로 공격자는 서명 세트를 제거했습니다 alg 에 none를,그리고 완전히 공격자가 제어하는 클레임으로 검증을 통해 항해했습니다. 관련 트릭은 RS256 을 HS256 으로 교환하므로 검증자는 공공의 HMAC 비밀로 키. 이 이유는 RFC 8725 - JSON 웹 토큰 모범 현재 관행 - 무딘: 검증자는 코드에 허용 알고리즘을 고정해야하고 토큰을 선택하게하지 마십시오. 라이브러리 호출 doesn't 에 명시 적 포함 된 경우 algorithms 목록, 오늘 수정하세요.
디코딩 대 검증 - 중요한 라인입니다. 디코딩은 읽기; 검증은 신뢰하는 것입니다. 코드의 차이:
// Decoding: no secret, no trust. Anyone can do this.
const payload = JSON.parse(
Buffer.from(token.split('.')[1], 'base64url').toString()
);
// Verifying: proves the signature AND pins the algorithm.
const verified = jwt.verify(token, secret, { algorithms: ['HS256'] });
온라인 디코더는 첫번째 일을 한다. 그것은 당신에게 주장을 보여줄 수 있다; 그것은 토큰이 진짜라고 말할 수 없고 - 가장해서도 안된다. 오직 verify를, 열쇠로, 저것을 한다. 해독된 그러나 검증되지 않은 요구에 허가 결정을 결코 내리지 말라.
마지막 규칙으로 이어집니다: JWT 페이로드에 비밀을 넣지 마십시오. 암호 없음, API 열쇠 없음, 자료 없음 you'd는 읽는 공격자를 염두에 둡니다. 페이로드는 건축에 의하여 공중 입니다 - 탐지를 반대하여 서명해, 읽기에 넓게 열려있는. it's가 토큰에 있는 경우에, 전체적인 인터넷이 그것을 볼 수 있다는 것을 가정하십시오.
일반적인 사용 사례
API 개발 중 401s 디버깅
401 은 HTTP 에서 가장 정보가 적은 상태 코드입니다. 서버가 아니오라고 말했지만 토큰이 만료 되었습니까? 잘못된 대상? 오래된 키로 서명 했습니까? 인터셉터 didn't 화재로 인해 완전히 누락 되었습니까? 실패한 요청에서 실제 토큰을 디코딩하면 검색 공간이 몇 초 만에 축소됩니다. 절반의 시간 exp 혼자 답합니다. 나머지 반은 비교하면서 iss 그리고 aud against your verifier's environment config 는 staging 에 대해 재생되는 dev 토큰을 찾거나,그 반대의 경우도 마찬가지입니다. 나는 디코더를 정확히 이 루프를 위해 내 HTTP 클라이언트 옆에 고정해 둡니다; it's a core entry in my API 디버깅 툴킷. 먼저 디코딩하고 미들웨어를 두 번째로 읽으십시오. 역순으로 한 번 1시간 40분 정도 소요되었으며 해당 강의에 대한 관심을 계속 수집할 계획입니다.
깜짝 로그아웃을 설명합니다
사용자가 보고 "it 는 저를 밖으로 기록하는 것을 계속하고," the token's 타임스탬프는 당신의 증인 진술입니다. 신선한 접근 토큰을 해독하고 사이 간격을 검사하십시오 iat 그리고 exp- 실제로 구성한 15 분입니까,아니면 env var 이 60 초로 재정의했습니까? 그런 다음 새로 고침 token's 7 일 창이 당신이 생각하는 것인지 확인하십시오. 시계 스큐는 여기에도 나타납니다: 발행 서버's 시계가 몇 분 빠르게 실행되면 토큰은 client's 계산에 의해 이미 고대 상태로 도착합니다. 그리고 물론 초-대-밀리초 비교 버그 - Toolz.dev 를 비트하는 것 -는 완벽하게 유효한 것을 보는 순간 스스로를 발표합니다 exp 토큰에서 귀하의 고객이 맹세하는 것이 만료되었습니다.
귀하의 신원 제공자가 토큰에 넣는 내용을 감사합니다
대부분의 팀은 실제로 IdP 민트 토큰을 읽은 적이 없으며,그것 & # 39;s 할 가치가 있습니다. 하나를 디코딩하면 전자 메일 주소,전체 이름,그림 URL,테넌트 식별자를 찾을 수 있습니다 - 모든 단일 API 요청에서 따라 타고 localStorage 에 저장되고 토큰에 손을 대는 모든 사람이 읽을 수있는 PII. Here& # 39;s 내 독선적 인 입장,그리고 I & # 39;ll 은 누구와도 논쟁합니다: don & # 39;t 는 JWT 페이로드에 사용자 이메일을 넣습니다. The sub 주장은 정확하게 존재한다 그래서 너는 불투명한 식별자를 나르고 인간적인 세부사항 서버 측을 위로 볼 수 있는다.모든 여분 주장은 자료 you're 방송 이고 바이트 you're 은 각 요구에 지불한다.디코딩하고,감사하고, 그 때 너의 IdP's 주장 지도를 손질한 간다.
권한 부여 디버깅 중 역할 및 범위 확인
인증은 당신이 누구인지; 권한 부여는 당신이 할 수있는 일을 말한다 - 그리고 권한이 잘못 동작하면 대답은 주장에있다. 사용자는 swears they're an admin but gets 403s? 그들의 토큰을 디코딩. 만약 role 라고 말합니다 user는, 토큰은 프로모션 전에 주조되었다 그들은 다시 로그인해야합니다 - 오래된 스냅 샷을 운반 무국적 토큰의 고전적인 결과. 역할이 존재하지만 여전히 액세스가 실패하면 정확한 주장 이름과 모양을 확인: roles 대 role, 배열 대 문자열, scope 공백으로 구분된 문자열 vs scp 배열로. 미들웨어 검사 payload.roles.includes('admin') 가지고 있는 페이로드에 반대합니다 role: "admin" 묵묵히 격분하게 실패합니다. 두 개의 디코딩된 토큰이 나란히 - 하나는 작동하고 하나는 작동하지 않음 - 보통 1 분 안에 정착합니다.
액세스 및 새로 고침 토큰 내용 비교
저와 같은 듀얼 토큰 설정에서는 두 토큰이 의미있게 다르게 보여야 하며,둘 다 디코딩하는 것이 감사입니다. 액세스 토큰: short exp게다가 API가 요청당 필요한 모든 것을 주장합니다. 새로 고침 토큰: 길다 exp, ᅡ jti 철회 추적을 위해,그리고 가능한 한 다른 것에 가깝지 않습니다. 새로 고침 토큰이 역할과 프로필 데이터를 전달하는 경우 something's off - it's 는 이제까지 하나의 엔드 포인트에만 제시되고 should't 는 액세스 토큰을 복제합니다's 작업. 이 병렬 검사는 또한 두 토큰이 실수로 동일한 TTL 을 얻는 당황스러운 버그 클래스를 잡아 "15 분 액세스 창 & quot; 보안 극장으로 전환합니다. 그 하나를 확인하는 방법을 알고 있는지 물어보십시오.
JWT 대 불투명한 세션 토큰: 정직한 비교
| JWT | 불투명한 세션 토큰 | |
|---|---|---|
| 무국적 | 독립형; 키가 있는 모든 서버는 조회 없이 확인합니다 | 서버 (또는 Redis 와 같은 공유 저장소) 는 모든 요청을 조회해야 합니다 |
| 철회 | 하드 - 까지 유효합니다 exp 상태를 다시 도입하는 데닐리스트를 구축하지 않는 한 |
사소한 - 서버 측 레코드를 삭제하면 토큰이 즉시 죽습니다 |
| 요청 당 크기 | 수백 바이트에서 1킬로바이트 이상까지 모든 요청 | ~32–64바이트 |
| 검증이 이루어지는 곳 | (공개) 키를 보유한 모든 곳에서 - 마이크로서비스에 적합합니다 | 세션 스토어가 사는 곳마다 |
| 신선함을 주장하세요 | 문제 시점의 스냅샷; 역할 변경은 재발행을 기다립니다 | 항상 최신 - 라이브 데이터를 읽습니다 |
| 디버깅 가능성 | 청구범위를 즉시 해독하고 읽으십시오 | 설계상 불투명; 매장 접근이 필요합니다 |
나는 Toolz.dev 와 I'll 를 위한 JWTs 를 아직도 당신에게 말합니다 they're 를 지나치게 규정했습니다. 철회 이야기는 진짜로 나쁘다: 당신이 사용자를 금지할 때,그들의 접근 토큰은 까지 작동 유지한다 exp- 내 액세스 토큰이 15 분 동안 살고 7 일 새로 고침 토큰이 서버 측을 죽일 수있는 이유입니다. 그 하이브리드는 정직한 패턴입니다: 저렴한 검증을위한 수명이 짧은 무국적 JWT,제어를위한 하나의 상태 저장 체크 포인트. you & # 39;re 하나의 데이터베이스로 모노리스를 실행하는 경우 일반 세션은 더 간단하고 작으며 즉시 취소 할 수 있습니다 - 분산 검증의 JWT & # 39;s 초능력은 당신이 don & # 39;t 가 가진 문제를 해결하고 있습니다.
동안 we're 비교 - HS256 대 RS256 한 눈에:
| HS256 | RS256 | |
|---|---|---|
| 키 모델 | 하나는 비밀 표지판을 공유했습니다 그리고 확인하다 | 개인 키 표시, 공개 키가 확인됩니다 |
| 누가 토큰을 주조 할 수 있습니다 | 비밀을 쥐고 있는 사람 | 개인 키 홀더만 |
| 최고의 핏 | 단일 서비스, 발급자 = 검증자 | 마이크로서비스, 타사 IdP, JWKS |
| 시그니처 크기/속도 | 더 작고, 더 빠르게 | 더 크고, 더 느리고, 배포하기에 더 안전합니다 |
자주 묻는 질문
온라인 디코더에 JWT를 붙여넣는 것이 안전한가요?
디코더가 클라이언트 측을 실행하는 경우에만. 실제 토큰은 라이브 자격 증명입니다 - someone's 서버에 전송하는 것은 자신의 로그에 작업 키를 심습니다. the Toolz.dev JWT 디코더는 브라우저에서 모든 디코딩을 수행하고 아무것도 전송하지 않습니다; 당신은 붙여 넣기하는 동안 네트워크 탭을보고 스스로이 확인할 수 있습니다. 디코더의 경우 당신은 할 수 있습니다't 확인 만료 또는 테스트 토큰 만 사용.
비밀 없이 JWT를 디코딩할 수 있나요?
예 - that's 사람들이 가장 놓치는 포인트. 헤더와 페이로드는 base64url 인코딩 JSON 이며, 인코딩은 암호화가 아닙니다. 누구나 키 없이 모든 클레임을 읽을 수 있습니다. 비밀 (또는 개인 키) 은 서명을 만들거나 확인하는 데만 필요합니다. 디코딩에는 아무것도 필요하지 않습니다; 신뢰하려면 검증이 필요합니다.
What's 디코딩과 JWT 확인의 차이점?
디코딩은 내용을 읽습니다: 점으로 분할,base64url-디코딩,JSON 구문 분석. 인증은 진위를 증명합니다: 비밀 또는 공개 키를 사용하여 서명을 다시 계산하거나 확인하고,알고리즘을 확인하고,만료를 확인합니다. 디코더는 토큰이 주장하는 것을 보여줍니다; 키를 사용하여 서버 측에서 수행 한 확인 만이 그것을 믿을지 여부를 알려줍니다. 디코딩되었지만 확인되지 않은 주장에 따라 절대로 승인하지 마십시오.
왜 내 JWT가 유효하지 않거나 만료된 것으로 표시됩니까?
가장 자주 exp 는 진정으로 통과했다 - 그것을 해독하고 날짜를 확인. 다음 용의자: 엉성한 복사 붙여 넣기에서 잘린 토큰, an aud 또는 iss that does't match your verifier's config,서버간의 클럭 스큐,또는 회전된 키의 서명. 디코딩된 경우 exp 괜찮아 보이지만 코드가 토큰을 거부하는지 확인하고 you're가 초와 밀리초를 비교하는지 확인하세요.
JWT는 암호화되어 있나요?
표준 JWTs - 기술적으로 JWS,당 RFC 7515 - 서명,암호화되지. 서명은 변조를 감지하지만 아무것도 숨기지 않습니다; 페이로드는 누구나 읽을 수 있습니다. 암호화 된 변형 (JWE) 이 존재하지만 일반적인 웹 인증에서는 드뭅니다. 실용적인 규칙: 모든 JWT 페이로드를 공개로 취급하고 암호,API 키 또는 민감한 데이터를 절대로 하나에 넣지 마십시오.
exp 클레임은 어떤 형식으로 되어 있나요?
exp 는 RFC 7519 에 정의된 대로 유닉스 시대 (1970 년 1 월 1 일 UTC) 이후 NumericDate: 초입니다. 에 대해서도 마찬가지입니다 iat 그리고 nbf. 고전적인 버그는 JavaScript's 를 사용하고 있습니다 Date.now()밀리초를 반환하는 - 즉시 만료된 것처럼 보이거나 56,000년경에 만료 날짜를 전달하는 토큰을 생성합니다. 디코딩된 타임스탬프에 5자리 연도가 표시되면 that's 버그가 발생합니다.
알그노 공격이란?
RFC 7519는 보안되지 않은 JWT를 허용합니다 "alg": "none" 그리고 빈 서명. 오래된 라이브러리는 header's 알고리즘 필드를 신뢰했기 때문에 공격자는 서명을 제거했습니다. set alg 에 none를,그리고 위조된 클레임으로 검증을 통과했습니다. JWT Best Current Practices 인 RFC 8725 는 검증자가 코드에 알고리즘의 명시적 허용-목록을 고정하고 토큰이 요구하는 것은 무엇이든 무시하도록 요구합니다.
HS256 또는 RS256 을 사용해야합니까?
HS256 는 서명 및 확인을 위해 하나의 공유 비밀을 사용합니다 - 간단하고 빠르며 자체 토큰을 발행하고 확인하는 단일 서비스에 적합합니다. RS256 은 개인 키로 서명하고 공개 키로 확인하므로 많은 서비스가 위조 할 수없이 검증 할 수 있습니다. 경험 법칙: monolith,HS256; microservices 또는 타사 ID 공급자,RS256.
감싸는 중
나는 구축했다 JWT 디코더 왜냐하면 Toolz.dev 자체를 구축하는 동안 계속 필요했기 때문입니다 - 동일한 15 분 액세스 토큰 및 7 일 새로 고침 토큰 I & # 39;이 가이드 전체에서 해부되었습니다. 그것은 즉시 디코딩하고 혼란의 90%를 유발하는 타임스탬프를 번역하며 토큰을 어디에도 보내지 않습니다. 그 마지막 부분은 isn & # 39;t a feature checkbox; 라이브 자격 증명을 처리하는 도구의 경우 it & # 39;s 전체 디자인.
토큰이 일일 디버깅의 일부인 경우 이웃도 자신의 유지 비용을 벌게 됩니다: the 타임스탬프 변환기 시대 고고학의 경우 Base64 변환기 원시 세그먼트를 찌르기 위해 JSON 포맷터 청구 얼룩의 경우 해시 생성기 when you're working with digests. 더 넓은 작업 흐름을 위해,나의 API 디버깅 도구 가이드 디코더가 루프에 맞는 위치를 다룹니다.
그리고 한 문장 버전을 모니터에 테이프로 붙이십시오: 디코딩은 토큰이 말하는 것을 알려주고,검증은 그것을 믿을 지 여부를 알려줍니다. 둘을 혼동하고 you'll 은 someone's 블로그 게시물의 오프닝 일화로 끝나는 버그의 종류를 발송했습니다. 이번에는 내 것이 었습니다.



