jwt前端解析
当我们做前后端分离项目时,需要将jwt保存在前端,有时候需要将jwt中的数据解析出来,网上有很多用第三方组件的方式,但是js的原生方法就也可以解决,虽然存在兼容等问题,但是修改一下也是可用的。
我们jwt 数据载体是使用的base64进行加密的,所以我们只需要对载体的字符串进行base64解码即可!
但是注意的是:base64对应的字符表,一共64个字符,包括26个字母的大小写、10个阿拉伯数字、+号和/号;附:(还有一个’ =’ 号一般用于后缀)。那么对于一些base64格式的输出就需要需要替换掉里面的一些不符合字符。
将base64转为json方式
方式一:
(一般将jwt字符串进行分割,得到有价值的base64字符段去解析)
可以这样(最优雅的解决掉)
需要吧‘_’,'-'进行转换否则会无法解析
var userinfo = JSON.parse(decodeURIComponent(escape(window.atob('base64字符串'.replace(/-/g, "+").replace(/_/g, "/"))))); //解析,需要吧‘_’,'-'进行转换否则会无法解析
供大家测试使用的base64码:
eyJzdWIiOiJkZWZhdWx0IiwidXBuIjoiYWRtaW4iLCJpc3MiOiJDTj10aG9yb3VnaCIsImlhdCI6MTY4NDE0NzUwNSwiZXhwIjoxNjg0MjA3NTA1LCJ1c2VySWQiOiIxIiwidXNlck5hbWUiOiLns7vnu5_nrqHnkIblkZgiLCJ1c2VyVHlwZSI6IjAiLCJyZWZyZXNoVG9rZW4iOiJhZWE5NmY4Yy1jNDM1LTRhNmUtYThlMS02OGI2ZWQwODNhMDciLCJqdGkiOiJhY2FjYmEwYy04Nzc4LTQzZTMtYjVjMC1iNjQ5ZTAxMTlmMmYifQ
方式二:
自己写一个utils来解析与生成base64码:
var Base64 = {
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encode: function(e) {
var t = "";
var n, r, i, s, o, u, a;
var f = 0;
e = Base64._utf8_encode(e);
while (f < e.length) {
n = e.charCodeAt(f++);
r = e.charCodeAt(f++);
i = e.charCodeAt(f++);
s = n >> 2;
o = (n & 3) << 4 | r >> 4;
u = (r & 15) << 2 | i >> 6;
a = i & 63;
if (isNaN(r)) {
u = a = 64
} else if (isNaN(i)) {
a = 64
}
t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
}
return t
},
decode: function(e) {
var t = "";
var n, r, i;
var s, o, u, a;
var f = 0;
e = e.replace(/[^A-Za-z0-9+/=]/g, "");
while (f < e.length) {
s = this._keyStr.indexOf(e.charAt(f++));
o = this._keyStr.indexOf(e.charAt(f++));
u = this._keyStr.indexOf(e.charAt(f++));
a = this._keyStr.indexOf(e.charAt(f++));
n = s << 2 | o >> 4;
r = (o & 15) << 4 | u >> 2;
i = (u & 3) << 6 | a;
t = t + String.fromCharCode(n);
if (u != 64) {
t = t + String.fromCharCode(r)
}
if (a != 64) {
t = t + String.fromCharCode(i)
}
}
t = Base64._utf8_decode(t);
return t
},
_utf8_encode: function(e) {
e = e.replace(/rn/g, "n");
var t = "";
for (var n = 0; n < e.length; n++) {
var r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r)
} else if (r > 127 && r < 2048) {
t += String.fromCharCode(r >> 6 | 192);
t += String.fromCharCode(r & 63 | 128)
} else {
t += String.fromCharCode(r >> 12 | 224);
t += String.fromCharCode(r >> 6 & 63 | 128);
t += String.fromCharCode(r & 63 | 128)
}
}
return t
},
_utf8_decode: function(e) {
var t = "";
var n = 0;
var r = c1 = c2 = 0;
while (n < e.length) {
r = e.charCodeAt(n);
if (r < 128) {
t += String.fromCharCode(r);
n++
} else if (r > 191 && r < 224) {
c2 = e.charCodeAt(n + 1);
t += String.fromCharCode((r & 31) << 6 | c2 & 63);
n += 2
} else {
c2 = e.charCodeAt(n + 1);
c3 = e.charCodeAt(n + 2);
t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
n += 3
}
}
return t
}
};
使用方式:
生成:
var enstr = Base64.encode(JSON.stringify({
"sub": "default",
"upn": "admin",
"iss": "CN=thorough",
"iat": 1684147505,
"exp": 1684207505,
"userId": "1",
"userName": "系统管理员",
"userType": "0",
"refreshToken": "aea96f8c-c435-4a6e-a8e1-68b6ed083a07",
"jti": "acacba0c-8778-43e3-b5c0-b649e0119f2f"
}));
console.log(enstr);
破解:
var destr = Base64.decode(enstr);
console.log(JSON.parse(destr));
方式三:
使用库文件:js-base64
npm install --save js-base64
import {decode} from 'js-base64'
console.log("解密:",decode('eyJraWQiOiJkZWZhdWx0IiwidHlwIjoiSldUIiwiYWxnIjoiUlMyNTYifQ'));
更多可以查看他们文档:https://www.npmjs.com/package/js-base64
以上base64解析原理:
如果你是在通过原始的手段去编码
,注意啊
const txt = new Buffer('文字').toString('base64');
//encodeURIComponent() 函数可以把字符串作为 URI 组件进行编码并且不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码
const urltxt = encodeURIComponent(txt);
console.log(urltxt)
//所对应的,在需要将base64转为utf-8,须提前用decodeURIComponent()进行一次解码,才可以保证解码成功,不乱码
//decodeURIComponent()函数可对 encodeURIComponent() 函数编码的 URI 进行解码。
const zurltxt = new Buffer(decodeURIComponent(urltxt), 'base64').toString('utf8');
console.log(zurltxt)
即
encodeURIComponent():把字符串作为URI 组件进行编码
decodeURIComponent():对 encodeURIComponent() 函数编码的 URI 进行解码
可以尝试用原始的btoa,atob去编码中文。
体验这个编码模式,中文也可以正常编码与解析
let msg = {name:"勇敢牛牛",age:18};
let base64 = btoa(unescape(encodeURIComponent(JSON.stringify(msg))));
console.log(base64);
let Tmsg = decodeURIComponent(escape(atob(base64)));
console.log(JSON.parse(Tmsg));
或者封装成一个函数
// 使用utf-8字符集进行base64编码
function utoa(str) {
return btoa(unescape(encodeURIComponent(str)));
}
// 使用utf-8字符集解析base64字符串
function atou(str) {
return decodeURIComponent(escape(atob(str)));
}
atou函数:其实该函数的关键是做了一个拉丁字符到utf-8字符的转换.
这里面的方法可以解析详细就可以看这里:
编程修养