2011-02-09 12 views
7

デスクトップアプリケーションでGoogle Data APIのユーザーを認証するための最良の方法は?Google Data API:デスクトップアプリケーションの認証方法

私はdocsを読んでいます。私のオプションはClientLoginまたはOAuthのようです。

ClientLoginの場合、ログイン/パスワード用のUI(およびこれをどこかに保存するなどの関連するもの)を実装する必要があるようです。デフォルトのログイン/パスワード画面をポップアップしてOSのキーチェーンを使用してパスワードなどを保存するサポートがあるのではないかと私は本当に思っています。それは標準的な手順ではないでしょうか?その実装をdevに残すことで(もちろん、開発者にそのimplを残す可能性もあります)、私は多くの人がここで非常に醜い解決策を思いついたと思います(小さなスクリプト)。

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) 

しかし、これは動作しません。 。このエラーが発生します:

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_urlgoogle_apps_domain=Noneから来ました。それは

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.

:ちょうどloginurl = request_token.generate_authorization_url()すなわち(つまりを離れたままにし、それは今のところ働く

私の現在のコード:。

下部にヒントをGoogleのOAuthページを開きます
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 

連絡先にアクセスしようとすると(つまり、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> 

私は間違った範囲を設定していたようです。 https(つまりSCOPES = [ "http://www.google.com/m8/feeds/" ])の代わりにhttpを使用すると動作します。

しかし、私は本当に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です。


私もどこ、どのように、ユーザーが何度も何度も、常にユーザーがアプリケーションを起動するたびに聞かれないように、私がアクセストークンおよび/またはリクエストトークンを保存する必要がありますどのくらいのために、疑問に思います。

答えて

2

OAuthはデスクトップアプリケーションでも使用できます。コンシューマキーと秘密の「匿名」は、そのようなアプリには完全に適しています。

ユーザーは自分自身を認証しません。プロバイダ(Google)からトークンを取得すると、そのユーザーはGoogleサービスにアクセスして使用できる信頼できるコンシューマ(アプリケーション)のトークンとしてユーザーから承認されます。ここで

はOAuthのた​​めに良いのpythonライブラリです:

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

ここでのOAuthの仕組みの概要です:ここで

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

も可能にする手順を説明し、Java用の例ですOAuth認証のために取られました:

HTH。

+0

ユーザーによる認可: は https://developers.google.com/accounts/docs/OAuth2InstalledApp https://developers.google.com/accounts/docs/OAuth2Login

テスト(これは、私はそれをやった方法です)好き?外部Webブラウザを開き、トークンが承認されているかどうか頻繁に再確認しますか?サンプルコードでは、Webブラウザがどこに開かれているのかわかりません。 – Albert

+0

また、gdataライブラリにはすでにOAuth用の関数が付属しているようです。だから私はそれのために別のライブラリが必要ないと思いますか?あるいは、すでにgdataに加えて、python-oauth2は何を提供していますか? – Albert

+0

3足OAuthは次のように動作します。1.プロバイダ(Google)からトークンとトークンシークレットを要求します2。ユーザーのWebブラウザを開いてプロバイダの認証URLに移動し、ユーザーがアクセスを許可することを確認できるようになり、確認コードが返されます。プロバイダのサイトでは、ベリファイアを提供するURL経由であなたに電話をかけることも、必要なベリファイアコードをユーザに与えることもできます。 3.元のトークンと検証者を使用して、プロバイダから最後のトークンを取得できます。 – ldx

関連する問題