如何在节点应用程序中解码google OAuth 2.0 JWT(OpenID Connect)? [英] How can I decode a google OAuth 2.0 JWT (OpenID Connect) in a node app?

查看:171
本文介绍了如何在节点应用程序中解码google OAuth 2.0 JWT(OpenID Connect)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里尝试使用Google OAuth在我的节点快速应用程序中验证用户。我可以成功地执行OAuth,它返回如下响应:

  {
access_token:'token string'
id_token:'id.string',
expires_in:3599,
token_type:承载
}

这一切都是有道理的,但是我无法为我的生活找出如何解码JWT。我所有这一切都没有经验,所以这对我来说有点陌生。



按照这里列出的说明: https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken 我正在尝试在我的节点应用程序本地解码JWT。 p>

我安装了 https://github.com/hokaccha/node-jwt - 简单的在我的节点环境。



我确定我需要使用这个证书( https://www.googleapis.com/oauth2/v1/certs )在所有这些以某种方式解码,但我在这里有一点损失。我真的不明白我如何将证书存入我的节点应用程序,之后如何使用node-jwt-simple。而且我也不太明白我什么时候需要提供一个新的证书,而不是使用缓存的证书。



任何人都有一些经验,可以帮助我吗?



感谢任何帮助。我完全失去了这一点。



**更新**



所以我做了一些进步...种类。
通过调用jwt.decode(id_token,certificate,true);我能够成功解码令牌。即使证书var是空对象{}。这让我有3个问题。
1:使用google的网址将证书存入我的快速应用程序的最佳方法是什么?
2:当我需要拉入新版本的时候,我怎么知道?
3:对于noVerify(jwt.decode中的第3个arg)来说,似乎是一个非常糟糕的想法。我怎么能把它放在工作中呢?
看起来可能是jwt-simple是期待hs256,令牌正在使用rs256。



再次,我在这方面没有经验,所以我可能会



*更新*
感谢Nat的帮助,我得到了这个工作!
我想我曾尝试过每一个JWT和JWS节点模块。我终于登陆了如下:
我发现我看不到的任何一个模块完全是我想要的模块。我创建了以下jwt解码助手方法,我用来解码id_token,所以我可以从标题中获取小孩。

  module.exports = {
decodeJwt:function(token){
var segments = token.split('。');

if(segments.length!== 3){
throw new Error('不够或太多的段');
}

//所有段应为base64
var headerSeg = segments [0];
var payloadSeg = segments [1];
var signatureSeg = segments [2];

// base64解码和解析JSON
var header = JSON.parse(base64urlDecode(headerSeg));
var payload = JSON.parse(base64urlDecode(payloadSeg));

return {
header:header,
payload:payload,
signature:signatureSeg
}

}
}

函数base64urlDecode(str){
return new Buffer(base64urlUnescape(str),'base64')。toString();
};

函数base64urlUnescape(str){
str + = Array(5 - str.length%4).join('=');
return str.replace(/ \- / g,'+')。replace(/ _ / g,'/');
}

我正在使用此解码来确定是否需要拉入新的公开证书来自: https://www.googleapis.com/oauth2/v1/certs



然后我使用该公共证书和node-jws( https://github.com/brianloveswords / node-jws )jws.verify(id_token,cert)验证签名!



Hooray!
再次感谢您在回复中给出的额外解释。这在帮助我了解我甚至想做什么方面有很大的帮助。希望这可能会帮助别人。

解决方案

从规范的角度来看,你遇到的是[OpenID Connect]。



id_token是一个[JWS]签名的[JWT]。在这种情况下,它是一个。用三个组件分隔字符串。第一部分是标题。第二个是有效载荷。第三是签名。每个都是Base64url编码的字符串。



当您解码标题时,您将获得以下内容:



{alg:RS256 ,kid:43ebb53b0397e7aaf3087d6844e37d55c5fb1b67}



alg表示签名算法是在[JWA]中定义的RS256。
kid表示与用于签名的密钥对应的公钥的密钥ID。



现在我准备回答你的一些问题:


2:我怎么知道什么时候需要拉一个新版本?


当缓存的证书文件(一个[JWK]文件)的孩子与标题中的孩子不匹配时,获取一个新的证书文件。 (BTW,从中提取证书的URL称为x5u。)


3:似乎传递为true for noVerify(3rd arg在jwt.decode)
是一个可怕的想法。如果没有通过
,那么我该如何工作?


确实。也许您可能想查看另一个库,如kjur.github.io/jsjws/。



参考




  • [OpenID Connect] openid .bitbucket.org / openid-connect-core-1_0.html

  • [JWS] tools.ietf.org/html/draft-ietf-jose-json-web-signature

  • [JWT] tools.ietf.org/html/draft-ietf-oauth-json-web-token

  • [JWK] tools.ietf.org / html / draft-ietf-oauth-json-web-keys

  • [JWA] tools.ietf.org/html/draft-ietf-jose-json-web-algorithms


I'm having a heck of a time here trying to use google OAuth to authenticate users in my node express app. I can successfully do the OAuth, which returns a response like so:

{
  access_token: 'token string',
  id_token: 'id.string',
  expires_in: 3599,
  token_type: "Bearer"
}

This all makes sense, but I can't for the life of me figure out how to decode the JWT. I am a bit inexperienced in all this, so this is all a bit foreign to me.

Following the instructions listed here: https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken I am attempting to decode the JWT locally in my node app.

I installed https://github.com/hokaccha/node-jwt-simple in my node environment.

And I'm pretty certain I need to use this certificate (https://www.googleapis.com/oauth2/v1/certs) in all this somehow to decode it, but I am at a bit of a loss here. I don't really understand how I get the certificate into my node app, and after that how to use it with node-jwt-simple. And I also don't really understand how I know when I need to pull a fresh certificate, vs using a cached one.

Anyone out there with some experience in this that can help me out?

Thanks for any help. I'm totally at a loss at this point.

** Update **

So I have made some progress... Kind of. By calling jwt.decode(id_token, certificate, true); I am able to successfully decode the token. Even if the certificate var is an empty object {}. This leaves me with 3 questions still. 1: What is the best way to get the certificate into my express app using the url from google? 2: How will I know when I need to pull in a fresh version of it? 3: It seems like passing in true for noVerify (3rd arg in jwt.decode) is a terrible idea. How can I get that to work without passing that in? It looks like perhaps jwt-simple is expecting hs256 and the token is using rs256.

Again, I'm super inexperienced in this, so I may be way off base here.

* UPDATE * Thanks to the help from Nat, I was able to get this working! I think I tried every single JWT and JWS node module out there. What I finally landed on is as follows: I found that none of the modules that I looked at did quite what I wanted out of the box. I created the following jwt decoding helper methods that I am using to decode the id_token, so I can get the kid from the header.

module.exports = {
  decodeJwt: function (token) {
    var segments = token.split('.');

    if (segments.length !== 3) {
      throw new Error('Not enough or too many segments');
    }

    // All segment should be base64
    var headerSeg = segments[0];
    var payloadSeg = segments[1];
    var signatureSeg = segments[2];

    // base64 decode and parse JSON
    var header = JSON.parse(base64urlDecode(headerSeg));
    var payload = JSON.parse(base64urlDecode(payloadSeg));

    return {
      header: header,
      payload: payload,
      signature: signatureSeg
    }

  }
}

function base64urlDecode(str) {
  return new Buffer(base64urlUnescape(str), 'base64').toString();
};

function base64urlUnescape(str) {
  str += Array(5 - str.length % 4).join('=');
  return str.replace(/\-/g, '+').replace(/_/g, '/');
}

I am using this decoding to determine if I need to pull in a new public cert from: https://www.googleapis.com/oauth2/v1/certs

Then I am using that public cert and node-jws (https://github.com/brianloveswords/node-jws) jws.verify(id_token, cert) to verify the signature!

Hooray! Thanks again for the extra explanation you gave in your response. That went a long way in helping me understand what I was even trying to do. Hope this might help others too.

解决方案

From the specification point of view, what you are encountering is [OpenID Connect].

id_token is a [JWS] signed [JWT]. In this case, it is a "." separated string with three components. The first portion is the header. The second is the payload. The third is the signature. Each of them are Base64url encoded string.

When you decode the header, you will get something like:

{"alg":"RS256","kid":"43ebb53b0397e7aaf3087d6844e37d55c5fb1b67"}

The "alg" indicates that the signature algorithm is RS256, which is defined in [JWA]. The "kid" indicates the key id of the public key that corresponds to the key used to sign.

Now I am ready to answer some of your questions:

2: How will I know when I need to pull in a fresh version of it?

When the kid of the cached cert file (a [JWK] file) does not match the kid in the header, fetch a new cert file. (BTW, the URL from which you pull the certs are called x5u.)

3: It seems like passing in true for noVerify (3rd arg in jwt.decode) is a terrible idea. How can I get that to work without passing that in?

Indeed. Perhaps you might want to look at another library such as kjur.github.io/jsjws/ .

References

  • [OpenID Connect] openid.bitbucket.org/openid-connect-core-1_0.html
  • [JWS] tools.ietf.org/html/draft-ietf-jose-json-web-signature
  • [JWT] tools.ietf.org/html/draft-ietf-oauth-json-web-token‎
  • [JWK] tools.ietf.org/html/draft-ietf-oauth-json-web-keys
  • [JWA] tools.ietf.org/html/draft-ietf-jose-json-web-algorithms

这篇关于如何在节点应用程序中解码google OAuth 2.0 JWT(OpenID Connect)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆