Google Data API:如何对桌面应用程序进行身份验证

我想知道在桌面应用中验证Google Data API用户的最佳/最简单的方法。

我阅读了文档,看起来我的选项是ClientLogin或OAuth。

对于ClientLogin,我似乎必须自己实现用户界面的登录/密码(以及相关的事情,比如保存在某处等)。 我真的不知道是否有更多的支持,可能会弹出一些默认的登录/密码屏幕,并使用操作系统钥匙串来存储密码等。我想知道为什么这种支持不存在? 这不是标准程序吗? 通过将这个实现留给开发者(当然,将这个impl留给开发者的可能性当然是好的),我猜测很多人在这里提出了非常难看的解决方案(当他们只是想把一个小脚本)。

OAuth似乎是更好的解决方案。 但是,似乎有一些代码丢失和/或我发现的大多数代码似乎只与Web应用程序有关。 特别是,我遵循了文档并到了这里。 在介绍中已经介绍了Web应用程序。 之后,我需要指定一个回调URL,这对于桌面应用程序来说没有意义。 我还想知道我应该放置什么样的消费者密钥/秘密,因为这对于桌面应用程序来说也没有意义(尤其是对于开源应用程序而言)。 我搜索了一下,在这里(在SO上)说我应该使用“匿名”/“匿名”作为消费者密钥/秘密; 但是它在Google文档中说了些什么? 如何在用户验证自己后获得令牌?

有没有一些示例代码? (不是使用硬编码的用户名/密码,而是使用可重复使用的完整身份验证方法。)

谢谢,阿尔伯特


我的代码到目前为止:

import gdata.gauth
import gdata.contacts.client

CONSUMER_KEY = 'anonymous'
CONSUMER_SECRET = 'anonymous'
SCOPES = [ "https://www.google.com/m8/feeds/" ] # contacts

client = gdata.contacts.client.ContactsClient(source='Test app')

import BaseHTTPServer
import SocketServer

Handler = BaseHTTPServer.BaseHTTPRequestHandler
httpd = BaseHTTPServer.HTTPServer(("", 0), Handler)
_,port = httpd.server_address

oauth_callback_url = 'http://localhost:%d/get_access_token' % port
request_token = client.GetOAuthToken(
    SCOPES, oauth_callback_url, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)

loginurl = request_token.generate_authorization_url(google_apps_domain=None)
loginurl = str(loginurl)
import webbrowser
webbrowser.open(loginurl)

但是,这不起作用。 我得到这个错误:

抱歉,您已到达未使用Google Apps的网域的登录页面。 请检查网址并重试。

我不太明白这一点。 当然,我不使用Google Apps。


嗯,这个错误来自于generate_authorization_url google_apps_domain=None 。 离开它(即只是loginurl = request_token.generate_authorization_url() ,它到目前为止工作。

我现在的代码:

import gdata.gauth
import gdata.contacts.client

CONSUMER_KEY = 'anonymous'
CONSUMER_SECRET = 'anonymous'
SCOPES = [ "https://www.google.com/m8/feeds/" ] # contacts

client = gdata.contacts.client.ContactsClient(source='Test app')

import BaseHTTPServer
import SocketServer

httpd_access_token_callback = None
class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path.startswith("/get_access_token?"):
            global httpd_access_token_callback
            httpd_access_token_callback = self.path
        self.send_response(200)
    def log_message(self, format, *args): pass
httpd = BaseHTTPServer.HTTPServer(("", 0), Handler)
_,port = httpd.server_address

oauth_callback_url = 'http://localhost:%d/get_access_token' % port
request_token = client.GetOAuthToken(
    SCOPES, oauth_callback_url, CONSUMER_KEY, consumer_secret=CONSUMER_SECRET)

loginurl = request_token.generate_authorization_url()
loginurl = str(loginurl)
print "opening oauth login page ..."
import webbrowser; webbrowser.open(loginurl)

print "waiting for redirect callback ..."
while httpd_access_token_callback == None:
    httpd.handle_request()

print "done"

request_token = gdata.gauth.AuthorizeRequestToken(request_token, httpd_access_token_callback)

# Upgrade the token and save in the user's datastore
access_token = client.GetAccessToken(request_token)
client.auth_token = access_token

这将打开谷歌OAuth页面底部的提示:

本网站尚未向Google注册以建立授权请求的安全连接。 除非您信任该网站,否则我们建议您拒绝访问。

但它仍然不起作用。 当我尝试访问联系人(即只是一个client.GetContacts() ),我得到这个错误:

gdata.client.Unauthorized: Unauthorized - Server responded with: 401, <HTML>
<HEAD>
<TITLE>Token invalid - AuthSub token has wrong scope</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Token invalid - AuthSub token has wrong scope</H1>
<H2>Error 401</H2>
</BODY>
</HTML>

好的,似乎我确实设置了错误的范围。 当我使用http而不是https (即SCOPES = [ "http://www.google.com/m8/feeds/" ] )时,它起作用。

但我真的很想使用https。 我想知道我该怎么做。


此外,此解决方案的另一个问题是:

在我的Google帐户的授权访问列表中,我现在有一堆这样的localhost条目:

localhost:58630 - 谷歌通讯录[撤销访问]
localhost:58559 - 谷歌通讯录[撤销访问]
localhost:58815 - 谷歌联系人[撤销访问]
localhost:59174 - 谷歌通讯录[撤销访问]
localhost:58514 - 谷歌通讯录[撤销访问]
localhost:58533 - 谷歌通讯录[撤销访问]
localhost:58790 - 谷歌通讯录[撤销访问]
localhost:59012 - 谷歌通讯录[撤销访问]
localhost:59191 - 谷歌通讯录[撤销访问]

我想知道如何避免它会做出这样的输入。

当我使用xoauth_displayname ,它会显示该名称,但仍然会生成多个条目(可能是因为每次都由于该URL大多不同(由于端口))。 我怎样才能避免这种情况?


我目前的代码现在在Github上。


我还想知道,我应该在哪里以及在多长时间内存储访问令牌和/或请求令牌,以便每次用户启动应用程序时都不会一直询问用户。


OAuth也可用于桌面应用。 消费者密钥和秘密'匿名'非常适合这样的应用程序。

用户不会验证他们自己。 您将从提供商(谷歌)获得令牌,然后这将被用户授权为可信用户(您的应用)的令牌,可以访问和使用他们的Google服务。

以下是一个用于OAuth的优秀python库:

https://github.com/simplegeo/python-oauth2

以下概述了OAuth的工作原理:

http://blog.doityourselfandroid.com/2010/11/07/google-oauth-overview/

以下是Java的一个示例,其中还解释了OAuth身份验证的步骤:

http://nilvec.com/implementing-client-side-oauth-on-android/

HTH。


这是您可以通过桌面应用程序从Google进行身份验证的方式。 (这是我做到的)https://developers.google.com/accounts/docs/OAuth2InstalledApp https://developers.google.com/accounts/docs/OAuth2Login

测试:https://www.googleapis.com/oauth2/v1/userinfo?access_token=ACCESS_TOKEN

链接地址: http://www.djcxy.com/p/50699.html

上一篇: Google Data API: how to do authentication for desktop applications

下一篇: Checking if an Admin and a Customer are logged in