如何使用oauth2.0在Django中检索Google通讯录?

时间:2016-10-20 17:21:32

标签: python django oauth-2.0 gdata google-contacts

我的应用已在Google注册,我启用了联系人API。

在第一个视图中,我获取了访问令牌,我将用户重定向到Google确认页面,系统会提示他提供访问其联系人的权限:

SCOPE = 'https://www.google.com/m8/feeds/'
CLIENT_ID = 'xxxxxxxx'
CLIENT_SECRET = 'xxxxxxxxx'
APPLICATION= 'example.com'
USER_AGENT = 'dummy-sample'
APPLICATION_REDIRECT_URI = 'http://example.com/oauth2callback/'

def import_contacts(request):

    auth_token = gdata.gauth.OAuth2Token(
        client_id=CLIENT_ID, client_secret=CLIENT_SECRET,
        scope=SCOPE, user_agent=USER_AGENT)

    authorize_url = auth_token.generate_authorize_url(
        redirect_uri=APPLICATION_REDIRECT_URI)

    return redirect(authorize_url)

如果用户点击“允许”,那么Google会重定向到我的处理程序,该处理程序将检索联系人:

def oauth2callback(request):
    code = request.GET.get('code', '')
    redirect_url = 'http://example.com/oauth2callback?code=%s' % code
    url = atom.http_core.ParseUri(redirect_url)

    auth_token.get_access_token(url.query)

    client = gdata.contacts.service.ContactsService(source=APPLICATION)
    auth_token.authorize(client)
    feed = client.GetContactsFeed()

正如您所看到的,我的问题是如何在第二个视图中获取auth_token对象,因为此代码在auth_token.get_access_token(url.query)行上失败。 我试过没有成功多个选项,比如将对象放在会话中,但它不可序列化。我也尝试了gdata.gauth.token_to_blob(auth_token)但是我只能检索令牌字符串而不是对象。使用gdata.gauth.ae_save()ae_load()似乎需要Google App Engine。

为了获取联系人,我看到的另一种方法是直接在第一个带有访问令牌的Django视图中请求它们,而不是使用代码交换令牌:

r = requests.get('https://www.google.com/m8/feeds/contacts/default/full?access_token=%s&alt=json&max-results=1000&start-index=1' % (self.access_token))

但这不是将用户重定向到谷歌页面,以便他们可以明确表示他们的批准。相反,它使用令牌直接提取联系人作为凭据。这是一种常见做法吗?你怎么看?我认为第一种方法是首选方法,但首先我必须设法获取auth_token对象..

1 个答案:

答案 0 :(得分:0)

最后,我能够序列化对象并将其放入会话中,这不是一种安全的方法,但至少它会指向正确的方向,以便我可以继续使用与社交相关的业务逻辑应用

import gdata.contacts.client

def import_contacts(request):

    auth_token = gdata.gauth.OAuth2Token(
        client_id=CLIENT_ID, client_secret=CLIENT_SECRET,
        scope=SCOPE, user_agent=USER_AGENT)

    authorize_url = auth_token.generate_authorize_url(
        redirect_uri=APPLICATION_REDIRECT_URI)
    # Put the object in the sesstion
    request.session['auth_token'] = gdata.gauth.token_to_blob(auth_token)

    return redirect(authorize_url)

def oauth2callback(request):
    code = request.GET.get('code', '')
    redirect_url = 'http://myapp.com/oauth2callback?code=%s' % code
    url = atom.http_core.ParseUri(redirect_url)
    # Retrieve the object from the session
    auth_token = gdata.gauth.token_from_blob(request.session['auth_token'])
    # Here is the tricky part: we need to add the redirect_uri to the object in addition
    auth_token.redirect_uri = APPLICATION_REDIRECT_URI

    # And this was my problem in my question above. Now I have the object in the handler view and can use it to retrieve the contacts.
    auth_token.get_access_token(url.query)
    # The second change I did was to create a ContactsClient instead of ContactsService
    client = gdata.contacts.client.ContactsClient(source=APPLICATION)
    auth_token.authorize(client)
    feed = client.GetContacts()

    all_emails = []
    for i, entry in enumerate(feed.entry):
        # Loop and fill the list with emails here
        ...

    return render_to_response('xxx/import_contacts.html', {'all_emails': all_emails},
                          context_instance=RequestContext(request))