programing

라이브러리를 사용하지 않고 jwt 토큰을 javascript로 디코딩하는 방법은 무엇입니까?

bestcode 2022. 9. 18. 12:55
반응형

라이브러리를 사용하지 않고 jwt 토큰을 javascript로 디코딩하는 방법은 무엇입니까?

JavaScript를 사용하여 JWT의 payload를 디코딩하려면 어떻게 해야 하나요?도서관도 없이.따라서 토큰은 프런트 엔드 앱에서 사용할 수 있는 페이로드 개체를 반환합니다.

토큰 예시:xxxxxxxxx.XXXXXXXX.xxxxxxxx

그 결과 payload가 됩니다.

{exp: 10012016 name: john doe, scope:['admin']}

주의: 시그니처를 검증하지 않고 토큰에서 JSON 페이로드만 추출합니다.이 페이로드가 조작되었을 가능성이 있습니다.

브라우저

작동 중인 유니코드 텍스트 JWT 파서 함수:

function parseJwt (token) {
    var base64Url = token.split('.')[1];
    var base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
    var jsonPayload = decodeURIComponent(window.atob(base64).split('').map(function(c) {
        return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));

    return JSON.parse(jsonPayload);
};

JWT 사용base64url(RFC 4648 5 5 )따라서 사용만atob(이것에 의해,base64)로는 불충분합니다.

Node.js

function parseJwt (token) {
    return JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
}

Try - Catch를 통한 간단한 기능

const parseJwt = (token) => {
  try {
    return JSON.parse(atob(token.split('.')[1]));
  } catch (e) {
    return null;
  }
};

감사합니다!

jwt-decode를 사용하면 다음과 같이 쓸 수 있습니다.

import jwt_decode from 'jwt-decode';

var token = 'eyJ0eXAiO.../// jwt token';

var decoded = jwt_decode(token);
console.log(decoded);
/*{exp: 10012016 name: john doe, scope:['admin']}*/

순수 자바스크립트를 사용할 수 있습니다.atob()토큰을 문자열로 디코딩하는 함수:

atob(token.split('.')[1]);

또는 직접 json 객체로 해석합니다.

JSON.parse(atob(token.split('.')[1]));

에 대해 읽다.atob()그리고.btoa()내장된 javascript 함수 Base64 인코딩 및 디코딩 - Web APIs | MDN.

function parseJwt(token) {
  var base64Payload = token.split('.')[1];
  var payload = Buffer.from(base64Payload, 'base64');
  return JSON.parse(payload.toString());
}
let payload= parseJwt("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
console.log("payload:- ", payload);

노드를 사용하는 경우 버퍼 패키지를 사용해야 할 수 있습니다.

npm install buffer
var Buffer = require('buffer/').Buffer

nodejs 환경에는 "window" 객체가 없기 때문에 다음 코드 행을 사용할 수 있습니다.

let base64Url = token.split('.')[1]; // token you get
let base64 = base64Url.replace('-', '+').replace('_', '/');
let decodedData = JSON.parse(Buffer.from(base64, 'base64').toString('binary'));

나한테는 완벽하게 먹히는군.도움이 됐으면 좋겠다.

Typescript 또는 vanilla JavaScript를 사용하는 경우 프로젝트 심플함수(@Rajan Maharjan의 답변에 기반)에 복사 붙여넣기를 할 수 있는 의존성이 전혀 없습니다.

이 답변은 npm 모듈에 의존하지 않을 뿐만 아니라 node.js 내장 모듈에 의존하지 않기 때문에 특히 좋습니다)에 의존하지 않음).Buffer(폴리가 채워지지 않는 한 처음부터 그렇게 할 필요는 없습니다)는, 여기서 사용되고 있는 다른 솔루션에서는, 물론 브라우저에 장해가 발생합니다.또한 런타임에 JSON.parse가 실패할 수 있으며, 이 버전(특히 Typescript)에서는 이 처리가 강제됩니다.JSDoc 주석을 사용하면 향후 코드 유지보수에 감사할 수 있습니다.:)

/**
 * Returns a JS object representation of a Javascript Web Token from its common encoded
 * string form.
 *
 * @template T the expected shape of the parsed token
 * @param {string} token a Javascript Web Token in base64 encoded, `.` separated form
 * @returns {(T | undefined)} an object-representation of the token
 * or undefined if parsing failed
 */
export function getParsedJwt<T extends object = { [k: string]: string | number }>(
  token: string,
): T | undefined {
  try {
    return JSON.parse(atob(token.split('.')[1]))
  } catch {
    return undefined
  }
}

완성을 위해 바닐라 자바스크립트 버전도 다음과 같습니다.

/**
 * Returns a JS object representation of a Javascript Web Token from its common encoded
 * string form.
 *
 * @param {string} token a Javascript Web Token in base64 encoded, `.` separated form
 * @returns {(object | undefined)} an object-representation of the token
 * or undefined if parsing failed
 */
export function getParsedJwt(token) {
  try {
    return JSON.parse(atob(token.split('.')[1]))
  } catch (error) {
    return undefined
  }
}

노드를 사용하는 경우.JS, 다음을 수행하여 네이티브 버퍼 모듈을 사용할 수 있습니다.

const token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImp0aSI6ImU3YjQ0Mjc4LTZlZDYtNDJlZC05MTZmLWFjZDQzNzhkM2U0YSIsImlhdCI6MTU5NTg3NzUxOCwiZXhwIjoxNTk1ODgxMTE4fQ.WXyDlDMMSJAjOFF9oAU9JrRHg2wio-WolWAkAaY3kg4';
const tokenDecodablePart = token.split('.')[1];
const decoded = Buffer.from(tokenDecodablePart, 'base64').toString();
console.log(decoded)

이제 가도 돼 :-)

@Peheje는 동작하지만 Unicode에 문제가 있습니다.수정하려면 https://stackoverflow.com/a/30106551/5277071;의 코드를 사용합니다.

let b64DecodeUnicode = str =>
  decodeURIComponent(
    Array.prototype.map.call(atob(str), c =>
      '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2)
    ).join(''))

let parseJwt = token =>
  JSON.parse(
    b64DecodeUnicode(
      token.split('.')[1].replace('-', '+').replace('_', '/')
    )
  )


let form = document.getElementById("form")
form.addEventListener("submit", (e) => {
   form.out.value = JSON.stringify(
      parseJwt(form.jwt.value)
   )
   e.preventDefault();
})
textarea{width:300px; height:60px; display:block}
<form id="form" action="parse">
  <textarea name="jwt">eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkrDtGhuIETDs8OoIiwiYWRtaW4iOnRydWV9.469tBeJmYLERjlKi9u6gylb-2NsjHLC_6kZNdtoOGsA</textarea>
  <textarea name="out"></textarea>
  <input type="submit" value="parse" />
</form>

이 답변을 기반으로 payload, header, expiration(Expiration Time), iat(Issued At)를 가져오기 위해 사용합니다.

function parseJwt(token) {
  try {
    // Get Token Header
    const base64HeaderUrl = token.split('.')[0];
    const base64Header = base64HeaderUrl.replace('-', '+').replace('_', '/');
    const headerData = JSON.parse(window.atob(base64Header));

    // Get Token payload and date's
    const base64Url = token.split('.')[1];
    const base64 = base64Url.replace('-', '+').replace('_', '/');
    const dataJWT = JSON.parse(window.atob(base64));
    dataJWT.header = headerData;

// TODO: add expiration at check ...


    return dataJWT;
  } catch (err) {
    return false;
  }
}

const jwtDecoded = parseJwt('YOUR_TOKEN') ;
if(jwtDecoded)
{
    console.log(jwtDecoded)
}

jwt.io에서 이 코드를 찾았는데 잘 작동합니다.

//this is used to parse base64
function url_base64_decode(str) {
  var output = str.replace(/-/g, '+').replace(/_/g, '/');
  switch (output.length % 4) {
    case 0:
      break;
    case 2:
      output += '==';
      break;
    case 3:
      output += '=';
      break;
    default:
      throw 'Illegal base64url string!';
  }
  var result = window.atob(output); //polifyll https://github.com/davidchambers/Base64.js
  try{
    return decodeURIComponent(escape(result));
  } catch (err) {
    return result;
  }
}

( 플랫폼이 있습니다.
(현재로서는) base64 길이가 유효하지 않은 문제에 직면해 있습니다.
그래서 좀 더 안정적인 방법이 필요했어요.

도움이 되었으면 좋겠어요.

node하는 경우 .js 16 을 할 수 .base64url★★★★★★★★★★★★★☆★

let payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url"));

다음 1개의 라이너 함수를 정의하여 사용할 수 있습니다.

jwtDecode = b => JSON.parse(Buffer.from(b.split('.')[1], 'base64').toString('binary'));

jwt.io의 모든 기능이 모든 언어를 지원하는 것은 아닙니다.NodeJs에서는

var decoded = jwt.decode(token);

답변은 GitHub - auth0/jwt-decode 에서 이루어집니다.전체 토큰을 전달할 수 있도록 문자열 분할 및 반환 개체 {header, payload, signature}을(를) 포함하도록 입력/출력이 변경되었습니다.

var jwtDecode = function (jwt) {

        function b64DecodeUnicode(str) {
            return decodeURIComponent(atob(str).replace(/(.)/g, function (m, p) {
                var code = p.charCodeAt(0).toString(16).toUpperCase();
                if (code.length < 2) {
                    code = '0' + code;
                }
                return '%' + code;
            }));
        }

        function decode(str) {
            var output = str.replace(/-/g, "+").replace(/_/g, "/");
            switch (output.length % 4) {
                case 0:
                    break;
                case 2:
                    output += "==";
                    break;
                case 3:
                    output += "=";
                    break;
                default:
                    throw "Illegal base64url string!";
            }

            try {
                return b64DecodeUnicode(output);
            } catch (err) {
                return atob(output);
            }
        }

        var jwtArray = jwt.split('.');

        return {
            header: decode(jwtArray[0]),
            payload: decode(jwtArray[1]),
            signature: decode(jwtArray[2])
        };

    };

심플 노드JSON Web 토큰(JWT)을 디코딩하기 위한 JS 솔루션

function decodeTokenComponent(value) {
    const buff = new Buffer(value, 'base64')
    const text = buff.toString('ascii')
    return JSON.parse(text)
}

const token = 'xxxxxxxxx.XXXXXXXX.xxxxxxxx'
const [headerEncoded, payloadEncoded, signature] = token.split('.')
const [header, payload] = [headerEncoded, payloadEncoded].map(decodeTokenComponent)

console.log(`header: ${header}`)
console.log(`payload: ${payload}`)
console.log(`signature: ${signature}`)

Node.js(TypeScript):

import { TextDecoder } from 'util';

function decode(jwt: string) {
    const { 0: encodedHeader, 1: encodedPayload, 2: signature, length } = jwt.split('.');

    if (length !== 3) {
        throw new TypeError('Invalid JWT');
    }

    const decode = (input: string): JSON => { return JSON.parse(new TextDecoder().decode(new Uint8Array(Buffer.from(input, 'base64')))); };

    return { header: decode(encodedHeader), payload: decode(encodedPayload), signature: signature };
}

★★★★★★★★★★★★★★★★ jose GitHub의 panva에 의해, 당신은 최소를 사용할 수 있습니다.import { decode as base64Decode } from 'jose/util/base64url'를 치환합니다.new Uint8Array(Buffer.from(input, 'base64'))base64Decode(input)Node.js의 Node.js의 Node.js.

이 질문을 검토한 후, 보다 풍부한 기능을 갖춘 솔루션을 다음에 제시하겠습니다.

const parseJwt = (token) => {
    try {
        if (!token) {
            throw new Error('parseJwt# Token is required.');
        }

        const base64Payload = token.split('.')[1];
        let payload = new Uint8Array();

        try {
            payload = Buffer.from(base64Payload, 'base64');
        } catch (err) {
            throw new Error(`parseJwt# Malformed token: ${err}`);
        }

        return {
            decodedToken: JSON.parse(payload),
        };
    } catch (err) {
        console.log(`Bonus logging: ${err}`);

        return {
            error: 'Unable to decode token.',
        };
    }
};

다음은 사용 예시를 제시하겠습니다.

const unhappy_path1 = parseJwt('sk4u7vgbis4ewku7gvtybrose4ui7gvtmalformedtoken');
console.log('unhappy_path1', unhappy_path1);

const unhappy_path2 = parseJwt('sk4u7vgbis4ewku7gvtybrose4ui7gvt.malformedtoken');
console.log('unhappy_path2', unhappy_path2);

const unhappy_path3 = parseJwt();
console.log('unhappy_path3', unhappy_path3);

const { error, decodedToken } = parseJwt('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c');
if (!decodedToken.exp) {
    console.log('almost_happy_path: token has illegal claims (missing expires_at timestamp)', decodedToken);
    // note: exp, iat, iss, jti, nbf, prv, sub
}

Stack Overflow 코드 스니펫툴에서는 실행할 수 없었습니다만, 그 코드를 실행하면 대략 다음과 같이 표시됩니다.

여기에 이미지 설명 입력

는 the든 the 를 만들었다.parseJwt함수는 항상 오브젝트를 반환합니다(스태틱한 이유로 어느 정도).

이를 통해 다음과 같은 구문을 사용할 수 있습니다.

const { decodedToken, error } = parseJwt(token);

그런 다음 런타임에 특정 유형의 오류를 테스트하여 명명 충돌을 방지할 수 있습니다.

코드에 가 낮은 사람이 든지 제 .next(person).

여기와 여기의 답변에 근거합니다.

const dashRE = /-/g;
const lodashRE = /_/g;

module.exports = function jwtDecode(tokenStr) {
  const base64Url = tokenStr.split('.')[1];
  if (base64Url === undefined) return null;
  const base64 = base64Url.replace(dashRE, '+').replace(lodashRE, '/');
  const jsonStr = Buffer.from(base64, 'base64').toString();
  return JSON.parse(jsonStr);
};

jwt-decode의 es-module 친화적인 간이 버전.js

function b64DecodeUnicode(str) {
  return decodeURIComponent(
    atob(str).replace(/(.)/g, function (m, p) {
      var code = p.charCodeAt(0).toString(16).toUpperCase();
      if (code.length < 2) {
        code = "0" + code;
      }
      return "%" + code;
    })
  );
}

function base64_url_decode(str) {
  var output = str.replace(/-/g, "+").replace(/_/g, "/");
  switch (output.length % 4) {
    case 0:
      break;
    case 2:
      output += "==";
      break;
    case 3:
      output += "=";
      break;
    default:
      throw "Illegal base64url string!";
  }

  try {
    return b64DecodeUnicode(output);
  } catch (err) {
    return atob(output);
  }
}

export function jwtDecode(token, options) {
  options = options || {};
  var pos = options.header === true ? 0 : 1;
  try {
    return JSON.parse(base64_url_decode(token.split(".")[pos]));
  } catch (e) {
    console.log(e.message);
  }
}

언급URL : https://stackoverflow.com/questions/38552003/how-to-decode-jwt-token-in-javascript-without-using-a-library

반응형