2013-11-23 32 views
32

我在这里尝试使用Google OAuth在我的节点快递应用程序中对用户进行身份验证。我可以成功做到的OAuth,它返回像这样的回应:如何在节点应用程序中解码Google OAuth 2.0 JWT(OpenID Connect)?

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

这都有道理,但我不能为我的生活弄清楚如何在JWT进行解码。我在这方面有点缺乏经验,所以这对我来说有点陌生。

按照此处列出的说明:https://developers.google.com/accounts/docs/OAuth2Login#validatinganidtoken我试图在我的节点应用程序本地解码智威汤逊。

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

而且我很确定我需要使用这个证书(https://www.googleapis.com/oauth2/v1/certs)来解码它,但我在这里有点遗憾。我并不真正了解如何将证书加入我的节点应用程序,之后如何将它与node-jwt-simple一起使用。而且我也并不真正了解我何时需要提取新证书,而不是使用缓存证书。

有人在那里有一些经验,可以帮助我吗?

感谢您的任何帮助。在这一点上我完全不知所措。

** **更新

所以,我已经取得了一些进展...类。 通过调用jwt.decode(id_token,certificate,true);我能够成功解码令牌。即使证书var是一个空对象{}。这留下了3个问题。 1:使用谷歌地址获取证书到我的快递应用程序的最佳方式是什么? 2:我如何知道何时需要使用新版本? 3:它看起来像传递true的noVerify(jwt.decode中的第3个参数)是一个可怕的想法。我怎样才能让它在没有通过的情况下工作? 它看起来也许jwt-simple期待hs256,令牌使用rs256。

再一次,我在这方面超级经验不足,所以我可能会在这里取得成功。

*更新* 感谢Nat的帮助,我能够得到这个工作! 我想我试过每一个JWT和JWS节点模块。我最终登陆的是如下: 我发现我看到的所有模块都完全不像我想要的那样。我创建了以下用于解码id_token的jwt解码助手方法,以便我可以从头文件中获取孩子。

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, '/'); 
} 

我使用这个解码,以确定如果我需要在一个新的公共证书拉来源:https://www.googleapis.com/oauth2/v1/certs

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

Hooray! 再次感谢您在回复中提供的额外解释。这在帮助我了解我甚至想要做什么方面取得了很大的进展。希望这可以帮助其他人。

回答

48

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

id_token是[JWS]签名的[智威汤逊]。在这种情况下,它是一个“。”分成三个部分的字符串。第一部分是标题。第二个是有效载荷。第三个是签名。它们中的每一个都是Base64url编码的字符串。

当你解码头,你会得到这样的:

{ “ALG”: “RS256”, “孩子”: “43ebb53b0397e7aaf3087d6844e37d55c5fb1b67”}

的 “ALG” 表示签名算法是[JWA]中定义的RS256。 “孩子”表示与用于签名的密钥对应的公钥的密钥ID。

现在我愿意回答大家的一些问题:

2:我怎么知道当我需要在它的新版本拉?

当缓存的证书文件([JWK]文件)的孩子与头部中的孩子不匹配时,获取新的证书文件。 (顺便说一句,从中你拉证书的网址被称为x5u。)

3:它看起来像真正的通过为noVerify(第三个参数中jwt.decode) 是一个可怕的想法。我怎样才能在没有通过 的情况下工作?

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

参考

  • [ID连接] 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-j ose-json-web-algorithms
+0

太棒了!非常感谢您的详细解释。这极大地帮助我理解我甚至想要做的事情。现在我知道如果我还有其他问题,我应该寻找什么。对此,我真的非常感激。 – ThePuzzleMaster

相关问题