6

Как декодировать JWT-токен в JavaScript без использования библиотеки?

14

Вопрос: Как декодировать полезную нагрузку JWT с помощью JavaScript без использования библиотеки?

Я пытаюсь декодировать JWT (JSON Web Token), чтобы получить объект полезной нагрузки, который затем смогу использовать в своем фронтенд-приложении.

У меня есть токен формата: xxxxxxxxx.XXXXXXXX.xxxxxxxx.

В результате я ожидаю получить следующий объект полезной нагрузки:

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

Как правильно реализовать этот функционал на чистом JavaScript? Спасибо за помощь!

5 ответ(ов)

12

Примечание: данный код не проверяет подпись токена, он просто извлекает 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), поэтому использование только atob (который работает с base64) недостаточно.

Node.js

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

Таким образом, эти функции позволяют вам извлекать полезные данные из JWT, но не забудьте о том, что они не проверяют подпись, и полученные данные могут быть поддельными.

1

Функция parseJwt, которую вы представили, выполняет разбор (декодирование) JWT-токена (JSON Web Token). Она использует конструкцию try-catch, чтобы обработать возможные ошибки при декодировании.

Вот как работает функция:

const parseJwt = (token) => {
  try {
    return JSON.parse(atob(token.split('.')[1])); // Разделяет токен, декодирует вторую часть и преобразует ее из JSON
  } catch (e) {
    return null; // В случае ошибки возвращает null
  }
};
  1. Разделение токена: Токен состоит из трех частей, разделенных точками. Функция берет вторую часть (payload), которая содержит полезную нагрузку.
  2. Декодирование: atob используется для декодирования строки из Base64 в ASCII.
  3. Парсинг: JSON.parse преобразует полученную строку в объект JavaScript.
  4. Обработка ошибок: Если произошла ошибка (например, токен некорректен или содержит недопустимые данные), функция вернет null, что позволяет избежать сбоев в программе.

Эта реализация проста и удобна для разбора JWT, и использование try-catch помогает безопасно обрабатывать ошибки. Если у вас есть дополнительные вопросы, не стесняйтесь обращаться!

0

Если вы хотите разобрать JWT (JSON Web Token) в Node.js, вы можете использовать следующий код:

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);

Обратите внимание, что если вы используете Node.js, вам может понадобиться установить пакет buffer, чтобы использовать класс Buffer. Для этого выполните команду:

npm install buffer

И затем подключите его в своем коде:

var Buffer = require('buffer/').Buffer;

Этот код разбирает токен, извлекает полезную нагрузку из его второй части (после первого .), декодирует ее из Base64 и затем преобразует в объект JavaScript для дальнейшей работы.

0

Если вы используете TypeScript или обычный JavaScript, вот простая функция без зависимостей, готовая для копирования и вставки в ваш проект (строится на основе ответа @Rajan Maharjan).

Этот ответ особенно хорош, не только потому что он не зависит от каких-либо npm-модулей, но и потому что он не использует никаких встроенных модулей Node.js (таких как Buffer), как это делают некоторые другие решения, и, конечно же, не будет работать в браузере (если не использовать полифилы, но в этом нет смысла с самого начала). Кроме того, JSON.parse может вызывать ошибки во время выполнения, и эта версия (особенно в TypeScript) заставит вас обработать их. Аннотации JSDoc сделают содержание вашего кода более понятным для будущих разработчиков. 😃

/**
 * Возвращает представление JS объекта Javascript Web Token из его распространенной закодированной
 * строковой формы.
 *
 * @template T ожидаемая структура парсенного токена
 * @param {string} token Javascript Web Token в форме base64, разделенный `.` 
 * @returns {(T | undefined)} представление объекта токена 
 * или undefined, если парсинг не удался
 */
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
  }
}

Для полноты картины вот версия на чистом JavaScript:

/**
 * Возвращает представление JS объекта Javascript Web Token из его распространенной закодированной
 * строковой формы.
 *
 * @param {string} token Javascript Web Token в форме base64, разделенный `.` 
 * @returns {(object | undefined)} представление объекта токена 
 * или undefined, если парсинг не удался
 */
export function getParsedJwt(token) {
  try {
    return JSON.parse(atob(token.split('.')[1]))
  } catch (error) {
    return undefined
  }
}
0

В среде Node.js объект "window" отсутствует, поэтому можно использовать следующий код:

let base64Url = token.split('.')[1]; // токен, который вы получаете
let base64 = base64Url.replace('-', '+').replace('_', '/');
let decodedData = JSON.parse(Buffer.from(base64, 'base64').toString('binary'));

Этот код отлично работает для меня. Надеюсь, это поможет!

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь