python - 在 Django 中使用 google.oauth2 id_token.verify_oauth2_token() 时出现“不正确的填充”错误
问题描述
我正在尝试从 React 前端到我的 Django 后端验证用户提交的 google 身份验证 JWT。我让我的前端使用 JWT 向后端发送一个请求,然后我的后端从请求中提取它并通过谷歌的推荐令牌身份验证来处理它。我的问题是,每次我通过 id_token.verify_ouath2_token() 处理从我的前端收到的 JWT 时,最终都会引发关于“不正确填充”的错误,最终源于令牌的 base64 编码。
但是,当通过复制粘贴我从 POST 请求中提取的令牌来手动测试它时,它工作得非常好并且不会引发错误。所以在我处理发布请求的某个地方出了点问题,但我不确定是什么。我尝试用 utf-8 和 ascii 解码 POST 请求,并简单地将 JWT 保留为我提取的字节形式。所有这些都会引发相同的错误,我很困惑。
这是我的代码:views.py
def login(request):
if request.method == "POST":
print(request.body.decode("ascii")) # For decoding. By copy/pasting this output into id_token.verify_oauth2_token instead of the token variable, the function returns successfully
try:
token = request.body.decode("ascii")
# Specify the CLIENT_ID of the app that accesses the backend:
idinfo = id_token.verify_oauth2_token(token, requests.Request(), "MY CLIENT ID")
# ID token is valid. Get the user's Google Account ID from the decoded token.
userid = idinfo['sub']
return(HttpResponse(userid))
except ValueError as e:
# Invalid token
print(e)
return(HttpResponse("Failure"))
else:
pass
和回溯
File "C:\Users\E\Google Drive\Projects\Django Project\Website\BackEnd\test\Main\views.py", line 80, in login
idinfo = id_token.verify_oauth2_token(token, requests.Request(), "MY CLIENT ID")
File "C:\Users\E\AppData\Local\Programs\Python\Python36-32\lib\site-packages\google\oauth2\id_token.py", line 147, in verify_oauth2_token
id_token, request, audience=audience, certs_url=_GOOGLE_OAUTH2_CERTS_URL
File "C:\Users\E\AppData\Local\Programs\Python\Python36-32\lib\site-packages\google\oauth2\id_token.py", line 126, in verify_token
return jwt.decode(id_token, certs=certs, audience=audience)
File "C:\Users\E\AppData\Local\Programs\Python\Python36-32\lib\site-packages\google\auth\jwt.py", line 230, in decode
header, payload, signed_section, signature = _unverified_decode(token)
File "C:\Users\E\AppData\Local\Programs\Python\Python36-32\lib\site-packages\google\auth\jwt.py", line 148, in _unverified_decode
signature = _helpers.padded_urlsafe_b64decode(signature)
File "C:\Users\E\AppData\Local\Programs\Python\Python36-32\lib\site-packages\google\auth\_helpers.py", line 215, in padded_urlsafe_b64decode
return base64.urlsafe_b64decode(padded)
File "C:\Users\E\AppData\Local\Programs\Python\Python36-32\lib\base64.py", line 133, in urlsafe_b64decode
return b64decode(s)
File "C:\Users\E\AppData\Local\Programs\Python\Python36-32\lib\base64.py", line 87, in b64decode
return binascii.a2b_base64(s)
binascii.Error: Incorrect padding
解决方案
经过一些实验,我想通了。看起来 request.body.decode("ascii") 最终生成了用双引号括起来的 JWT,而双引号是导致问题的原因。从字符串中剥离它们后,它可以完美地工作。
views.py 中的最终代码
@csrf_exempt
def login(request):
if request.method == "POST":
try:
token = request.body.decode("ascii").strip("\"")
# Specify the CLIENT_ID of the app that accesses the backend:
idinfo = id_token.verify_oauth2_token(token, requests.Request(), "MY CLIENT ID")
推荐阅读
- angular - filterOptions in Autocomplete does not work
- robotframework - Swedish characters and Robot Framework
- django - 从 wagtailstreamforms 中删除内置字段
- angular - mat-nav-item 不是已知元素
- android - 语音搜索无法从 ok google
- r - Export table to pretty XLS/open document spreadsheet
- python-3.x - signalR in python, then RecursionError
- filter - 使用 RediSearch 过滤 ID
- c++ - C++17文件路径分解成文件夹名
- java - 我们如何将 java 对象传递给 groovyx.net.http.RestClient 的 POST 调用