我想知道在桌面应用中为Google Data API用户进行身份验证的最佳/最简单方法。
我通读了docs,似乎我的选项是ClientLogin或OAuth。
对于ClientLogin,似乎我必须自己实现用于登录/密码的UI(以及相关的东西,比如在某处保存等)。我真的很想知道是否有更多的支持,可能会弹出一些默认的登录/密码屏幕,并使用操作系统密钥链来存储密码等。我想知道为什么没有这样的支持?那不是标准程序吗?通过将该实现留给开发人员(当然,将开发者留给开发者的可能性当然是好的),我猜想很多人在这里提出了非常丑陋的解决方案(当他们只是想要将一个小脚本混在一起时) )。
OAuth似乎是更好的解决方案。但是,似乎缺少一些代码和/或我发现的大多数代码似乎只与Web应用程序相关。 Esp。,我按照文档进行了here。已经在介绍中,它谈到了Web应用程序。然后,我需要指定一个对桌面应用程序没有意义的回调URL。此外,我想知道我应该放置哪些消费者密钥/秘密,因为这对于桌面应用程序也没有意义(特别是对于开源应用程序而言)。我搜索了一下,据说here (on 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。
啊,该错误来自google_apps_domain=None
中的generate_authorization_url
。把它留下(即只是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
这将打开Google 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 - Google通讯录[撤销访问权限]
localhost:58559 - Google通讯录[撤销访问]
localhost:58815 - Google通讯录[撤销访问]
localhost:59174 - Google通讯录[撤销访问]
localhost:58514 - Google通讯录[撤销访问]
localhost:58533 - Google通讯录[撤销访问权限]
localhost:58790 - Google通讯录[撤销访问]
localhost:59012 - Google通讯录[撤销访问]
localhost:59191 - Google通讯录[撤销访问]
我想知道如何避免这样做。
当我使用xoauth_displayname
时,它会显示该名称,但仍会生成多个条目(可能是因为每次URL仍然大部分不同(因为端口))。我怎么能避免这种情况?
我目前的代码现在位于Github。
我也想知道,我应该在何处,如何以及在多长时间内存储访问令牌和/或请求令牌,这样每次用户启动应用程序时都不会一次又一次地询问用户。
答案 0 :(得分:2)
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。
答案 1 :(得分:2)
这是您通过桌面应用程序从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