如何在不使用库的情况下在 javascript 中解码 jwt 令牌?

IT技术 javascript jwt
2021-01-14 09:14:35

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

示例令牌: xxxxxxxxx.XXXXXXXX.xxxxxxxx

结果是有效载荷:

{exp: 10012016 name: john doe, scope:['admin']}
6个回答

工作 unicode 文本 JWT 解析器功能:

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

    return JSON.parse(jsonPayload);
};
这个解决方案甚至可以用在 Postman(tests tap)中,因为它不需要任何额外的库安装。我用它从身份验证令牌中提取用户 ID。
2021-03-30 09:14:35
注意:在 Postman 中,我必须从中删除“window”JSON.parse(window.atob(base64))才能使其工作。只是return JSON.parse(atob(base64));然后postman.setEnvironmentVariable("userId", parseJwt(jsonData.access_token)); “access_token”在我的情况下是响应令牌值的关键(在你的情况下可能会有所不同)。
2021-03-30 09:14:35
也许对某些人来说微不足道,但不要忘记通过添加 const atob = require('atob'); 来添加 atob 作为依赖项。
2021-04-02 09:14:35
如果您使用的是 NodeJS,并且无法访问 atob,请改用以下代码: Buffer.from(base64, 'base64').toString()
2021-04-02 09:14:35
最好使用jwt-decodemodule,因为它很小但处理起来更好一些。
2021-04-11 09:14:35

带有 try-catch 的简单功能

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

谢谢!

@Pang atob() 和 btoa() 使用的算法在 RFC 4648 中指定。链接:developer.mozilla.org/en-US/docs/Glossary/Base64
2021-03-19 09:14:35
JWT 使用 base64urlRFC 4648 §5)。此答案使用 base64。这个答案是错误的。
2021-03-20 09:14:35
@RajanMaharjan MDN 页面说:“atob() 和 btoa() 使用的算法在RFC 4648,第 4 节中指定,但JWTJWS)使用在RFC 4648,第 5 节中定义的 base64url 编码不同。另请参阅Base64 -维基百科上的变体汇总表
2021-03-20 09:14:35
漂亮、简洁并使用所有本地方法!
2021-03-28 09:14:35
atob有已知的unicode 问题
2021-04-10 09:14:35

您可以使用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']}*/
“我的意思是没有图书馆。”
2021-03-18 09:14:35
@ApertureSecurity 你需要捕捉这个错误,但不可否认,这就是我不想使用这个库的原因
2021-03-31 09:14:35
他们是这个图书馆的问题。主要是和firefox一起使用。我遇到的问题是,如果由于注销或过期而导致令牌 == null ; 这只会导致页面出错。
2021-04-03 09:14:35
这似乎不支持 GZIP。事实上,我找不到任何支持 GZIP 声明的 JS 库。
2021-04-09 09:14:35

您可以使用纯 javascriptatob()函数将令牌解码为字符串:

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

或者直接解析成json对象:

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

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

@Pang 谢谢!我没有意识到有区别。这只是向我指出了我们的应用程序存在的解码错误的解决方案。
2021-03-27 09:14:35
JWT 使用 base64urlRFC 4648 §5)。此答案使用 base64。这个答案是错误的。
2021-04-01 09:14:35
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
我使用它而不是atob因为它已被弃用。
2021-03-25 09:14:35