Django 1.7 google oauth2令牌验证失败

编程入门 行业动态 更新时间:2024-10-24 10:26:36
本文介绍了Django 1.7 google oauth2令牌验证失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在尝试通过验证Google令牌来访问Django应用程序中的用户日历的过程。虽然我已经在网路上发现了几个迹象,但我遇到了一个400错误代码回应我的回调函数(Bad Request)。

.py

# - * - 编码:utf-8 - * - import os import argparse import httplib2 import log from apiclient.discovery import build from oauth2client import tools from oauth2client.django_orm导入存储从oauth2client导入xsrfutil 从oauth2client.client导入flow_from_clientsecrets 从django.http导入HttpResponse 从django.http导入HttpResponseBadRequest 从django .http import httpResponseRedirect from django.shortcuts import render_to_response from django.core.urlresolvers import reverse from django.contrib import auth from django.contrib.auth.decorators import login_required 从django.conf导入设置 from apps.tecnico.models import Credentia ls,Flow CLIENT_SECRETS = os.path.join( os.path.dirname(__ file__),'../../client_secrets.json') @login_required def index(request): storage = Storage(Credentials,'id',request.user,'credential') FLOW = flow_from_clientsecrets( CLIENT_SECRETS, scope ='https://www.googleapis/auth/calendar.readonly', redirect_uri ='http:// MY_URL:8000 / oauth2 / oauth2callback') credential = storage.get()如果凭证为无或credential.invalid为True: FLOW.params ['state'] = xsrfutil.generate_token( settings.SECRET_KEY,request .user) authorize_url = FLOW.step1_get_authorize_url()f = Flow(id = request.user,flow = FLOW) f.save()返回HttpResponseRedirect(authorize_url) else: http = httplib2.Http() http = credential.authorize(http) se rvice = build(serviceName ='calendar',version ='v3',http = http, developerKey ='MY_DEV_KEY_FROM_GOOGLE_CONSOLE') events = service.events() 'primary')。execute() return render_to_response('calendario / welcome.html',{'events':events ['items'],}) @login_required def auth_return(request):如果不是xsrfutil.validate_token( settings.SECRET_KEY,request.REQUEST ['state'],request.user) : return HttpResponseBadRequest() storage = Storage(Credentials,'id',request.user,'credential') FLOW = Flow.objects.get(id = request .user $。$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ b

models.py

往复m oauth2client.django_orm import FlowField,CredentialsField [...] class Credentials(models.Model): id = models.ForeignKey(User,primary_key = True) credential = CredentialsField() class Flow(models.Model): id = models.ForeignKey(User,primary_key = True) flow = FlowField()

我下载了 client_secrets.json 文件直接从Google开发者控制台。 开发者控制台中指定的客户端ID类型是Web应用程序,我认为是正确的。 我注意到的是,如果我删除令牌验证码块:

如果不是xsrfutil.validate_token( settings.SECRET_KEY,request.REQUEST ['state'],request.user): return HttpResponseBadRequest()

一切正常,流程和凭据正确存储在数据库中,我可以阅读日历。我可能会遇到什么问题?

编辑:我还检查了传出(Google)和传入(回调)数据:

OUTGOING :

请求。用户: admin settings.SECRET_KEY: I_AM_NOT_WRITING_IT_HERE FLOW.params ['state']: SOME_OTHER_RANDOM_STUFF / pre>

收入:

request.user: admin settings.SECRET_KEY: I_AM_NOT_WRITING_IT_HERE FLOW.params ['state']: SOME_OTHER_RANDOM_STUFF

数据是相同的,至少是一个打印到控制台。此外,通过控制台的生成/验证操作正常工作(xsrfutil.validate_token返回True,包括测试和实际数据,包括用户模型实例)。我更加困惑。

解决方案

我已经在几个小时内完全相同的问题,我想出了解决方案@Ryan Spaulding和@Hans Z回答。它的工作原理

这是因为Django 1.7使用request.REQUEST为上面的状态变量返回一个unicode对象。我以前使用过Django 1.6,它用来返回一个字符串。

这里可以找到更多的细节。 github/google/google-api-python-client/issues/58 我写了这篇文章以备将来参考。

如果不是xsrfutil.validate_token( settings.SECRET_KEY, str(request.REQUEST ['state ']), request.user): return HttpResponseBadRequest()

I'm trying to get through the process of authenticating a Google token for accessing a user's calendar within a Django application. Although I've followed several indications found on the web, I'm stuck with a 400 error code response to my callback function (Bad Request).

views.py

# -*- coding: utf-8 -*- import os import argparse import httplib2 import logging from apiclient.discovery import build from oauth2client import tools from oauth2client.django_orm import Storage from oauth2client import xsrfutil from oauth2client.client import flow_from_clientsecrets from django.http import HttpResponse from django.http import HttpResponseBadRequest from django.http import HttpResponseRedirect from django.shortcuts import render_to_response from django.core.urlresolvers import reverse from django.contrib import auth from django.contrib.auth.decorators import login_required from django.conf import settings from apps.tecnico.models import Credentials, Flow CLIENT_SECRETS = os.path.join( os.path.dirname(__file__), '../../client_secrets.json') @login_required def index(request): storage = Storage(Credentials, 'id', request.user, 'credential') FLOW = flow_from_clientsecrets( CLIENT_SECRETS, scope='www.googleapis/auth/calendar.readonly', redirect_uri='MY_URL:8000/oauth2/oauth2callback' ) credential = storage.get() if credential is None or credential.invalid is True: FLOW.params['state'] = xsrfutil.generate_token( settings.SECRET_KEY, request.user) authorize_url = FLOW.step1_get_authorize_url() f = Flow(id=request.user, flow=FLOW) f.save() return HttpResponseRedirect(authorize_url) else: http = httplib2.Http() http = credential.authorize(http) service = build(serviceName='calendar', version='v3', http=http, developerKey='MY_DEV_KEY_FROM_GOOGLE_CONSOLE') events = service.events().list(calendarId='primary').execute() return render_to_response('calendario/welcome.html', { 'events': events['items'], }) @login_required def auth_return(request): if not xsrfutil.validate_token( settings.SECRET_KEY, request.REQUEST['state'], request.user): return HttpResponseBadRequest() storage = Storage(Credentials, 'id', request.user, 'credential') FLOW = Flow.objects.get(id=request.user).flow credential = FLOW.step2_exchange(request.REQUEST) storage.put(credential) return HttpResponseRedirect("MY_URL:8000/caly")

models.py

from oauth2client.django_orm import FlowField, CredentialsField [...] class Credentials(models.Model): id = models.ForeignKey(User, primary_key=True) credential = CredentialsField() class Flow(models.Model): id = models.ForeignKey(User, primary_key=True) flow = FlowField()

I've downloaded the client_secrets.json file directly from the Google Dev Console. The specified Client ID type in the Dev Console is "web application", which I think is correct. What I've noticed is, if I remove the token validation code block:

if not xsrfutil.validate_token( settings.SECRET_KEY, request.REQUEST['state'], request.user): return HttpResponseBadRequest()

everything works correctly, flow and credentials get correctly stored in the database and I'm allowed to read the calendar. What can I possibly be wrong with?

EDIT: I've also checked outgoing (to Google) and incoming (to callback) data:

OUTGOING:

request.user: admin settings.SECRET_KEY: I_AM_NOT_WRITING_IT_HERE FLOW.params['state']: SOME_OTHER_RANDOM_STUFF

INCOMING:

request.user: admin settings.SECRET_KEY: I_AM_NOT_WRITING_IT_HERE FLOW.params['state']: SOME_OTHER_RANDOM_STUFF

Data is identical, at least to a print to console. Also, the generation/validation operations via console work correctly (xsrfutil.validate_token returns True, both with test and real data, including User model instances). I'm even more puzzled.

解决方案

I have struggled exact the same issue for several hours, and I figured out the solution of which @Ryan Spaulding and @Hans Z answered. It works!

This is due to the fact Django 1.7 returns a unicode object for the state variable above using request.REQUEST. I was previously using Django 1.6 which used to return a string.

One can find more detail here. github/google/google-api-python-client/issues/58 I wrote this post for future reference.

if not xsrfutil.validate_token( settings.SECRET_KEY, str(request.REQUEST['state']), request.user): return HttpResponseBadRequest()

更多推荐

Django 1.7 google oauth2令牌验证失败

本文发布于:2023-10-18 13:17:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1504331.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:令牌   Django   google

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!