如何使用JavaScript解码JWT的有效负载?没有图书馆。令牌只返回一个有效负载对象,前端应用可以使用它。

示例令牌:xxxxxxxxx.XXXXXXXX.xxxxxxxx

结果就是有效载荷:

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

当前回答

根据这里和这里的回答:

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

其他回答

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,你可能需要使用缓冲包:

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

我在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长度无效的问题。 所以,我需要一种更稳定的方法。

我希望这对你有所帮助。

你可以使用纯javascript atob()函数将token解码为字符串:

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

或者直接解析成json对象:

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

阅读关于atob()和btoa()内置javascript函数Base64编码和解码- Web api | MDN。

如果你正在使用Typescript或普通JavaScript,这里有一个零依赖,准备复制粘贴到你的项目简单函数(基于@Rajan Maharjan的回答)。

This answer is particularly good, not only because it does not depend on any npm module, but also because it does not depend an any node.js built-in module (like Buffer) that some other solutions here are using and of course would fail in the browser (unless polyfilled, but there's no reason to do that in the first place). Additionally JSON.parse can fail at runtime and this version (especially in Typescript) will force handling of that. The JSDoc annotations will make future maintainers of your code thankful. :)

/**
 * 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
  }
}

为了完成,这里还有一个普通的javascript版本:

/**
 * 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
  }
}

一个es模块友好的简化版本的jwt-decode.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);
  }
}