Node JS JWT使用Google的公钥验证令牌

七月

我正在阅读https://developers.google.com/actions/identity/google-sign-in指南以了解身份验证流程。现在,我需要访问用户的个人资料信息,因此我将使用带有代码的JWT库:

var decoded = jwt.verify(token, google_key,{algorithms: ['RS256'] });

该指南说:

使用您语言的JWT解码库来解码令牌,并使用Google的公共密钥(以JWKPEM格式提供)来验证令牌的签名。

因此,我决定通过以下代码使用PEM格式:

{
  "6f6781ba71199a658e760aa5aa93e5fc3dc752b5": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIPFwAmiva4MkwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0xOTA0MDIxNDQ5MThaFw0xOTA0MTkwMzA0MThaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUnbzv92s5aD1gmiF71M7tPT+XcQWRc45Y\nQKRflT7sQuEYVx9Ke6D5fuOeThQl7YjLOXFlhLOyyFSBMC9dKQtAJuQ1P2CqKA6Y\nTtfvRQAppqrcivJH/Iz3aSmYF4fTOg1EWv7R/28BOu3cTar2grIpPXo0TLNaq6uT\n3DlyB0QHbs4Xfz1+0Urwf4E63IHWAbOIu9dVjhRNV8Y497xUpO3ZN81at1zjSC30\nvyJbiEIPMyVgJlD7rV0uGP+a4hhcNcN8yofVgr8loLMCjDPO7DrMJYt31xQQCdyi\n0RsSxBQaqGh/soiy5f3pqMZko5YoGS/ME5TOvwRo5ThgYDI6/JUnAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQC8E4nZ3Sz61gQfOOq3/YpstWrONNol\nH6+L2KyU0+63wG9huxLHJOQ0Xj7oooOjSv4prOE91F3sUjE7P+aVTrwbLpaIpmbd\nloHI6h4yvjWmfdijo8VqSgZyXXhs4USLPEANux870XWEnWXkpR9QeSRQnZuCR2tF\n4nqDN1DMaLv6XCa2q7JPS27tBo9rMxsvk4SQUeSj6qAMyudST1AKDEZkqRdIDUqn\nuaWltHIlky8NUw7gkjOBMIIpIkQapBJ6WDZALebCNsaLbpvTQl3r5ttgW/aSsiXW\nKaJWL3reZU1mVb7JVBoRi8Fks19SnX753fhd4OAdgt91QzVIf7dwY1PG\n-----END CERTIFICATE-----\n",
  "a4313e7fd1e9e2a4ded3b292d2a7f4e519574308": "-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIILHP1ZKgNVzIwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0xOTAzMjUxNDQ5MThaFw0xOTA0MTEwMzA0MThaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCU7f9ChF38PxQcCMVx2DT/wY6IvJajhWKL\nLxwMs0Z/xPV5CWqqE9hma8Y4+HIgtZn0Uic5dP0DMfko9946cwTPLhOp8Yu11wCW\n5+oAt7+q6yartJI0hV9LDmI9mPNeTcFePOgU1kt+qyiqF4bN6T6wlXVOLklBDaFE\n9JlCFtr3FWfobxTGvm6BWEdDbk/ocvhpyOG6+lI8QWfu2K8QiFZkQvfkJ6od6V/7\njxYDg8vNFW98UxL6Fbp6uNfu7FP2aPy5PvMaXjX/MF32UyfYJB4/dosN5AWgVotp\nfY1ly1EBISvPof0whdCeAzWmIqdzziGaJ/L5kCw+kFzHDuF4WlhHAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQCOWDJs2YU7wLenPV0X8Q9LZLX0K+zb\n5HOoKEnf1ZAv4pg9GY0c3DNHfXrknjH+vPM0XbymEK+8EN8/6MBw96U2Lqxxcksj\nCZfK0FnIzT+ROE/FtrHHTnjqcd4aRES5Ffg7EU8lInUhqgmL/q7ZrZ1xBuz1cHPm\nza3aV/gaTs0cjEJWbNkLjDH5j55TBTXxmO32jgsh7i1uTnk1+P0SZKEgXWgKlCmG\nBP0Vx4+IEMfJvy8qdP/yJ50kGwaHjyMNdnxU33zylilxwXPdLWdV9N4KwTuLh4QF\n26EE8nUSCeP9tKKgdKsD/Q/wvuwBGQp4UVx4g/nsZHzxcdONdlhWYlVs\n-----END CERTIFICATE-----\n"
}

但是实际上我不知道从此证书中提取公共密钥来使用我之前说过的verify()指令。

(我尝试使用此Json变量,但出现此错误:)

UnhandledPromiseRejectionWarning: Error: PEM_read_bio_PUBKEY failed

如何从证书中获取公共密钥?我正在使用Nodejs。提前致谢。

劳尔·达维拉(Raul Davila)

PUBLIC KEY是实际的字符串:

"-----BEGIN CERTIFICATE-----\nMIIDJjCCAg6gAwIBAgIIPFwAmiva4MkwDQYJKoZIhvcNAQEFBQAwNjE0MDIGA1UE\nAxMrZmVkZXJhdGVkLXNpZ25vbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTAe\nFw0xOTA0MDIxNDQ5MThaFw0xOTA0MTkwMzA0MThaMDYxNDAyBgNVBAMTK2ZlZGVy\nYXRlZC1zaWdub24uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wggEiMA0GCSqG\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDUnbzv92s5aD1gmiF71M7tPT+XcQWRc45Y\nQKRflT7sQuEYVx9Ke6D5fuOeThQl7YjLOXFlhLOyyFSBMC9dKQtAJuQ1P2CqKA6Y\nTtfvRQAppqrcivJH/Iz3aSmYF4fTOg1EWv7R/28BOu3cTar2grIpPXo0TLNaq6uT\n3DlyB0QHbs4Xfz1+0Urwf4E63IHWAbOIu9dVjhRNV8Y497xUpO3ZN81at1zjSC30\nvyJbiEIPMyVgJlD7rV0uGP+a4hhcNcN8yofVgr8loLMCjDPO7DrMJYt31xQQCdyi\n0RsSxBQaqGh/soiy5f3pqMZko5YoGS/ME5TOvwRo5ThgYDI6/JUnAgMBAAGjODA2\nMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoGCCsG\nAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4IBAQC8E4nZ3Sz61gQfOOq3/YpstWrONNol\nH6+L2KyU0+63wG9huxLHJOQ0Xj7oooOjSv4prOE91F3sUjE7P+aVTrwbLpaIpmbd\nloHI6h4yvjWmfdijo8VqSgZyXXhs4USLPEANux870XWEnWXkpR9QeSRQnZuCR2tF\n4nqDN1DMaLv6XCa2q7JPS27tBo9rMxsvk4SQUeSj6qAMyudST1AKDEZkqRdIDUqn\nuaWltHIlky8NUw7gkjOBMIIpIkQapBJ6WDZALebCNsaLbpvTQl3r5ttgW/aSsiXW\nKaJWL3reZU1mVb7JVBoRi8Fks19SnX753fhd4OAdgt91QzVIf7dwY1PG\n-----END CERTIFICATE-----\n"

在您的示例中,Google提供了两个密钥。要知道必须使用哪个,我们首先需要提取一些存储在JWT头中的信息。为此,我们可以使用相同的jsonwebtoken库:

const header = jwt.decode(YOUR_JWT_HERE, { complete: true }).header;
/*
header = {
    alg: 'RS256',
    kid: '6f6781ba71199a658e760aa5aa93e5fc3dc752b5',
    typ: 'JWT'
}
*/

如您所见,header.kid匹配从Google检索的证书中的项目。那就是您必须用来验证JWT的那个。最后,代码如下所示:

const jwt = require('jsonwebtoken');

const token = YOUR_JWT_VALUE;
const certificates = {
    "6f6781ba71199a658e760aa5aa93e5fc3dc752b5": "-----BEGIN CERTIFICATE-----\nMIID[...]dwY1PG\n-----END CERTIFICATE-----\n",
    "a4313e7fd1e9e2a4ded3b292d2a7f4e519574308": "-----BEGIN CERTIFICATE-----\nMIID[...]hWYlVs\n-----END CERTIFICATE-----\n",
};

// Get header information from token
const header = jwt.decode(token, { complete: true }).header;
// Get the corresponding public key specified in header
const cert = certificates[header.kid];

// Verify token
jwt.verify(token, cert, { algorithms: ['RS256'] }, (err, payload) => {
    if (err) {
      // Not a valid token
      console.log('Error:', err);
      return;
    }

    // Token successfully verified
    console.log('Payload:', payload);
});

注意:Google的证书会不时更改。为了简化答案,我将它们声明为常量,但是您必须牢记这一点。来自Google

这些键定期旋转;检查响应中的Cache-Control标头,以确定何时应再次检索它们。

资料来源:

  • 在此处从JWT获取标头信息
  • 指南向阿德里安·安科纳大喊。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用 Node js 验证 Google ID 令牌

Node.js权限被拒绝的公钥

Node.JS验证Google身份验证令牌

如何使用node.js生成DER格式的私有EC私钥/公钥对,其中公钥被压缩?

验证Google ID令牌并使用node.js中的回调数据

验证jwt令牌并使用Node JS代理到另一台服务器

Node.js使用令牌ExpressJ进行身份验证

Node.js-如何使用访问/身份验证令牌?

无法使用csurf(Node.js)验证我的CSRF令牌

验证Node.js中的Nimbus JOSE + JWT令牌(Java)吗?

验证Android应用程序使用Node.JS服务器检索到的Google访问令牌

使用Node JS生成Twillio访问令牌

使用Node JS对Google API进行身份验证

无法使用Node.js验证Google服务帐户

如何使用Node.js在基于JWT令牌的错误消息中获取状态代码?

如何使用Node.js进行JWT令牌到每个路由的通用绑定并表达

node.js:意外令牌{

使用 Node.js 加密生成多对公钥/私钥

如何使用Node JS在HTML页面上传递令牌以验证用户

使用node.js管理员SDK创建令牌时的Firebase REST身份验证

如何使用基于令牌的身份验证在Node.js中实现基于角色的授权?

使用Node JS中的Keycloak访问令牌对Rest API进行身份验证

如何在Node.js中使用承载令牌实现socket.io身份验证

oAuth 2.0访问令牌验证node.js

如何使用js(node.js)创建承载令牌?

Node.js-XML验证

Node.js的验证库

使用Node.js的网页中的JWT身份验证系统

使用公钥验证端点签名JWT