3

好吧,我正在尝试用我的 django 项目实现 google oauth 身份验证。

我按照这里的指南:

https://developers.google.com/accounts/docs/OAuth2Login?hl=de-DE

我得到了交换代码的响应。我得到了一个字符串类型的 json,其中包含多个信息,如 access_token、id_token 等。

Id_token 是一个以 base64 编码的加密签名 JSON 对象。我尝试使用 python 模块 base64 解码 id_token,但失败了。

我也试过 PyJWT,失败了。

有没有办法解码和验证它?

4

3 回答 3

7

知道这是一篇旧帖子,但我是通过 Google 找到的,所以我认为其他人可能会加入...

我最终做了:

segments = response['id_token'].split('.')

if (len(segments) != 3): 
   raise Exception('Wrong number of segments in token: %s' % id_token) 

b64string = segments[1]
b64string = b64string.encode('ascii') 
padded = b64string + '=' * (4 - len(b64string) % 4) 
padded = base64.urlsafe_b64decode(padded)
于 2014-02-12T22:52:28.210 回答
3

ID 令牌(又名 JSON Web 签名 (JWS))有 3 个由.字符分隔的部分:

Header.Payload.Signature

我们可以通过拆分token来获取各个部分:

parts = token.split(".")

现在我不知道原因,但是这些部分没有base64填充。也许是因为它没有被强制执行(见这个)?而 python base64 库需要它。

填充字符为=,并且填充应添加到 base64 字符串,使其长度为 4 个字符的倍数。例如,如果字符串是 14 个字符,则它应该==在末尾有填充,以便总共有 16 个字符。

所以计算正确填充的公式是这样的:

4 - len(base64_string) % 4

在我们添加正确的填充并解码字符串之后:

payload = parts[1]
padded = payload + '=' * (4 - len(payload) % 4)

base64.b64decode(填充)

我们将得到一个 JSON 对象的字符串表示形式,我们可以将其转换为 JSON:

json.loads(base64.b64decode(padded))

最后我们可以把所有东西都放在一个方便的函数中:

import base64
import json


def parse_id_token(token: str) -> dict:
    parts = token.split(".")
    if len(parts) != 3:
        raise Exception("Incorrect id token format")

    payload = parts[1]
    padded = payload + '=' * (4 - len(payload) % 4)
    decoded = base64.b64decode(padded)
    return json.loads(decoded)

想了解更多关于 id token 的详情,请查看 Takahiko Kawasaki(authlete.com 创始人)的优秀文章

于 2019-12-11T14:35:46.233 回答
2

嗯,我知道为什么...

我使用 base64.b46decode(id_token) 对其进行解码。但是,我应该将 id_token 拆分为“。” 并分别解码。所以我可以从 id_token 中获取标题、声明和签名。

忽略那些小“。”我太愚蠢了。在字符串中......

于 2013-06-04T19:15:14.397 回答