草庐IT

python - 谷歌数据 API : how to do authentication for desktop applications

coder 2023-08-21 原文

我想知道在桌面应用程序中为 Google 数据 API 验证用户身份的最佳/最简单方法。

我通读了 docs我的选项似乎是 ClientLogin 或 OAuth。

对于 ClientLogin,我似乎必须自己实现用于登录名/密码的 UI(以及相关的事情,例如将其保存在某处等)。我真的很想知道那里是否有更多的支持可能会弹出一些默认的登录/密码屏幕并使用操作系统钥匙串(keychain)来存储密码等。我想知道为什么没有这样的支持?这不是标准程序吗?通过将该实现留给开发人员(好吧,将实现留给开发人员的可能性当然很好),我猜很多人在这里想出了非常丑陋的解决方案(当他们只是想拼凑一个小脚本时).

OAuth 似乎是更好的解决方案。但是,似乎缺少一些代码和/或我发现的大多数代码似乎只与 Web 应用程序相关。 Esp.,我按照文档得到了here .在介绍中,它谈到了 Web 应用程序。稍后,我需要指定一个对桌面应用程序没有意义的回调 URL。另外我想知道我应该输入什么消费者 key / secret ,因为这对于桌面应用程序也没有真正意义(尤其是对于开源应用程序)。我搜索了一下,据说是here (on SO)我应该使用“匿名”/“匿名”作为消费者 key / secret ;但是它在谷歌文档中的什么地方说的?以及如何在用户通过身份验证后获取 token ?

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

谢谢, 阿尔伯特


到目前为止我的代码:

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)

但是,这不起作用。我收到此错误:

Sorry, you've reached a login page for a domain that isn't using Google Apps. Please check the web address and try again.

我不太明白。当然,我不使用 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 页面,底部有提示:

This website has not registered with Google to establish a secure connection for authorization requests. We recommend that you deny access unless you trust the website.

不过还是不行。当我尝试访问联系人(即只是一个 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:58630 — Google Contacts [ Revoke Access ]
localhost:58559 — Google Contacts [ Revoke Access ]
localhost:58815 — Google Contacts [ Revoke Access ]
localhost:59174 — Google Contacts [ Revoke Access ]
localhost:58514 — Google Contacts [ Revoke Access ]
localhost:58533 — Google Contacts [ Revoke Access ]
localhost:58790 — Google Contacts [ Revoke Access ]
localhost:59012 — Google Contacts [ Revoke Access ]
localhost:59191 — Google Contacts [ Revoke Access ]

我想知道如何才能避免它生成这样的条目。

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


我当前的代码现在在 Github 上.


我还想知道我应该在哪里、如何以及多长时间存储访问 token 和/或请求 token ,这样用户就不会在每次用户启动应用程序时总是一次又一次地被询问。

最佳答案

OAuth 也可用于桌面应用程序。消费者 key 和 secret “匿名”非常适合此类应用。

用户不会对自己进行身份验证。您将从提供商 (Google) 处获得一个 token ,然后用户将其授权为受信任的消费者(您的应用)的 token ,通过该 token 可以访问和使用他们的 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.

关于python - 谷歌数据 API : how to do authentication for desktop applications,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4944331/

有关python - 谷歌数据 API : how to do authentication for desktop applications的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  4. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  5. Python 相当于 Perl/Ruby ||= - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。

  6. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  7. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  10. 【鸿蒙应用开发系列】- 获取系统设备信息以及版本API兼容调用方式 - 2

    在应用开发中,有时候我们需要获取系统的设备信息,用于数据上报和行为分析。那在鸿蒙系统中,我们应该怎么去获取设备的系统信息呢,比如说获取手机的系统版本号、手机的制造商、手机型号等数据。1、获取方式这里分为两种情况,一种是设备信息的获取,一种是系统信息的获取。1.1、获取设备信息获取设备信息,鸿蒙的SDK包为我们提供了DeviceInfo类,通过该类的一些静态方法,可以获取设备信息,DeviceInfo类的包路径为:ohos.system.DeviceInfo.具体的方法如下:ModifierandTypeMethodDescriptionstatic StringgetAbiList​()Obt

随机推荐