[尝试使用googleapiclient
和oauth2client
创建django的google登录名。
我能够打开主页,并成功重定向到google登录。登录后,它将重定向到我收到此错误的主页。
views.py
import httplib2
from googleapiclient.discovery import build
from django.http import HttpResponseBadRequest
from django.http import HttpResponseRedirect
from .models import CredentialsModel
from gfglogin import settings
from oauth2client.contrib import xsrfutil
from oauth2client.client import flow_from_clientsecrets
from oauth2client.contrib.django_util.storage import DjangoORMStorage
from django.shortcuts import render
from httplib2 import Http
def home(request):
print("*****home*****")
status = True
if not request.user.is_authenticated:
return HttpResponseRedirect('admin')
storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
credential = storage.get()
print(f"credential: {credential}")
print(f"storage: {storage}")
try:
access_token = credential.access_token
resp, cont = Http().request("https://www.googleapis.com/auth/gmail.readonly",
headers={'Host': 'www.googleapis.com',
'Authorization': access_token})
except:
status = False
print('Not Found')
return render(request, 'index.html', {'status': status})
################################
# GMAIL API IMPLEMENTATION #
################################
# CLIENT_SECRETS, name of a file containing the OAuth 2.0 information for this
# application, including client_id and client_secret, which are found
# on the API Access tab on the Google APIs
# Console <http://code.google.com/apis/console>
FLOW = flow_from_clientsecrets(
settings.GOOGLE_OAUTH2_CLIENT_SECRETS_JSON,
scope='https://www.googleapis.com/auth/gmail.readonly',
redirect_uri='http://127.0.0.1:8080/oauth2callback',
prompt='consent')
def gmail_authenticate(request):
print("*****gmail_authenticate*****")
storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
credential = storage.get()
print(f"credential: {credential}")
if credential is None or credential.invalid:
FLOW.params['state'] = xsrfutil.generate_token(settings.SECRET_KEY,
request.user)
authorize_url = FLOW.step1_get_authorize_url()
return HttpResponseRedirect(authorize_url)
else:
http = httplib2.Http()
http = credential.authorize(http)
service = build('gmail', 'v1', http=http)
print('access_token = ', credential.access_token)
status = True
return render(request, 'index.html', {'status': status})
def auth_return(request):
print("*****auth_return*****")
get_state = bytes(request.GET.get('state'), 'utf8')
if not xsrfutil.validate_token(settings.SECRET_KEY, get_state,
request.user):
return HttpResponseBadRequest()
credential = FLOW.step2_exchange(request.GET.get('code'))
print(f"credential: {credential}")
storage = DjangoORMStorage(CredentialsModel, 'id', request.user, 'credential')
storage.put(credential)
print(f"storage: {storage}")
print("access_token: %s" % credential.access_token)
return HttpResponseRedirect("/")
错误:
System check identified no issues (0 silenced).
June 06, 2020 - 14:38:49
Django version 3.0.7, using settings 'gfglogin.settings'
Starting development server at http://127.0.0.1:8080/
Quit the server with CTRL-BREAK.
[06/Jun/2020 14:39:00] "GET /admin/ HTTP/1.1" 200 3042
*****home*****
credential: None
storage: <oauth2client.contrib.django_util.storage.DjangoORMStorage object at 0x0000014A630EABE0>
Not Found
[06/Jun/2020 14:39:05] "GET / HTTP/1.1" 200 327
*****gmail_authenticate*****
credential: None
[06/Jun/2020 14:39:07] "GET /gmailAuthenticate HTTP/1.1" 302 0
*****auth_return*****
credential: <oauth2client.client.OAuth2Credentials object at 0x0000014A6322BA00>
storage: <oauth2client.contrib.django_util.storage.DjangoORMStorage object at 0x0000014A6322B550>
access_token: ya29.a0AfH6SMBLyCWC3cV4iiMk0jWUJaw8ruUFoBqFTkM5LT2acAc6FelcoADU3tn67RslO-24dKEFqrdp4tcLFVuEIMvmn7cHKeb8XeZ9YNQozRoRSTU6hs-jMA9bHP10epw1ImbBaY8SUgQUtF75mRRniR0aELEmzTVKGe8
[06/Jun/2020 14:40:26] "GET /oauth2callback?state=VaASAVe2IusAHCsQfc7EfToxNTkxNDM0NTQ3&code=4/0gFCWPMx4qTUrv4wUWpSKbA8Z_rTaZb-YGGDRrK4NsK2UiW6f4MpA_g1Pr5RpyGcRxbCtWlH6qHvKIJvbpG_L9c&scope=https://www.googleapis.com/auth/gmail.readonly HTTP/1.1" 302 0
*****home*****
Internal Server Error: /
Traceback (most recent call last):
File "D:\PERSONAL DATA\env\lib\site-packages\django\core\handlers\exception.py", line 34, in inner
response = get_response(request)
File "D:\PERSONAL DATA\env\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response
response = self.process_exception_by_middleware(e, request)
File "D:\PERSONAL DATA\env\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "D:\PERSONAL DATA\raw_login\google-oauth-mail\gfgauth\views.py", line 23, in home
credential = storage.get()
File "D:\PERSONAL DATA\env\lib\site-packages\oauth2client\client.py", line 407, in get
return self.locked_get()
File "D:\PERSONAL DATA\env\lib\site-packages\oauth2client\contrib\django_util\storage.py", line 58, in locked_get
if len(entities) > 0:
File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\query.py", line 258, in __len__
self._fetch_all()
File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\query.py", line 1261, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\query.py", line 74, in __iter__
for row in compiler.results_iter(results):
File "D:\PERSONAL DATA\env\lib\site-packages\django\db\models\sql\compiler.py", line 1096, in apply_converters
value = converter(value, expression, connection)
TypeError: from_db_value() missing 1 required positional argument: 'context'
SO之一,建议将context
参数替换为*args, **kwargs
。我无法在源代码中看到from_db_value
方法。
versions:
django == 3.0.7
python == 3.8
任何人都可以回答这个问题并提供帮助吗?
[我也看到oauth2client
已贬值。是否有其他我可以遵循的带有清晰示例的库?或任何人都可以发布示例代码吗?
在github issue中,有人说
您不能将oauth2client的存储与google-auth一起使用。谷歌认证 凭据相对直接可以持久保存,请参阅: https://github.com/GoogleCloudPlatform/google-auth-library-python-oauthlib/blob/master/google_auth_oauthlib/tool/main.py#L80
但是,作为新手,我无法理解实现这一点。请帮助!
问题似乎出在oauth2client
上,它不再得到更新或支持。从自述文件:
注意:oauth2client现在已弃用。不会再向库中添加任何功能,核心团队正在拒绝支持。我们建议您使用google-auth和oauthlib。有关弃用的更多详细信息,请参见oauth2client弃用。
所以我建议您看一下这两个软件包,然后将它们集成。
这里的重点是,您应该对选择的教程更加小心。该版本使用了Django 2.0,该版本已超过一年未得到支持。始终寻找与最新版本或最新LTS版本匹配的教程,否则您就会遇到麻烦。