如何使用JavaScript解码JWT的有效负载?没有图书馆。令牌只返回一个有效负载对象,前端应用可以使用它。
示例令牌:xxxxxxxxx.XXXXXXXX.xxxxxxxx
结果就是有效载荷:
{exp: 10012016 name: john doe, scope:['admin']}
如何使用JavaScript解码JWT的有效负载?没有图书馆。令牌只返回一个有效负载对象,前端应用可以使用它。
示例令牌:xxxxxxxxx.XXXXXXXX.xxxxxxxx
结果就是有效载荷:
{exp: 10012016 name: john doe, scope:['admin']}
当前回答
如果使用node.js 16或更高版本,可以使用内置的base64url编码器/解码器。
let payload = JSON.parse(Buffer.from(token.split(".")[1], "base64url"));
其他回答
@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>
答案基于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])
};
};
简单的功能与试接
const parseJwt = (token) => {
try {
return JSON.parse(atob(token.split('.')[1]));
} catch (e) {
return null;
}
};
谢谢!
如果你正在使用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
}
}
由于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'));
它非常适合我。希望能有所帮助。