好吧,我正在尝试使用我的django项目实施Google oauth身份验证。
我按照指南进行操作:
https://developers.google.com/accounts/docs/OAuth2Login?hl=de-DE
我从交换代码得到了回应。我有一个字符串类型json,其中包含多个信息,如access_token,id_token等。
Id_token是以base 64编码的加密签名的JSON对象。 我尝试用python模块base64解码id_token,但失败了。
我也试过PyJWT,失败了。
有没有办法解码和验证它?
答案 0 :(得分:5)
知道这是一篇很老的帖子,但我是通过谷歌发现的,所以我认为其他人可能会参与......
我最终做了:
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)
答案 1 :(得分:2)
好吧,我弄明白了为什么......
我使用base64.b46decode(id_token)对其进行解码。 但是,我应该将id_token拆分为'。'并分别解码它们。 所以我可以从id_token获得标题,声明和签名。
我太愚蠢了,因为无视那些小'。'在字符串....
答案 2 :(得分:0)
ID令牌(又名JSON Web签名(JWS))由3个部分组成,各部分之间用.
字符分隔:
Header.Payload.Signature
我们可以通过分割令牌来获取每个部分:
parts = token.split(".")
现在我不知道原因了,但是这些部分没有base64填充。也许是因为它没有被强制执行(请参见this)? 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令牌的更多详细信息,请检查Takahiko Kawasaki(authlete.com的创始人)出色的article