0

gdata、appengine、OAuth2を使ったシンプルなHelloWorldを試してみました。この投稿Googleの公式投稿を読みました。

問題1

最初の投稿によると、私のアプリはパート7「コードを使用してアクセストークンを取得する」で失敗します:

Traceback (most recent call last):
  File "[$PATH]/dev/outils/google_appengine/google/appengine/ext/webapp/_webapp25.py", line 701, in __call__
    handler.get(*groups)
  File "[$PATH]/dev/outils/google_appengine/google/appengine/ext/webapp/util.py", line 68, in check_login
    handler_method(self, *args)
  File "[$PATH]/dev/projets/xxx/main.py", line 76, in get
    token.get_access_token(url.query)
  File "[$PATH]/dev/projets/xxx/gdata/gauth.py", line 1296, in get_access_token
    'redirect_uri': self.redirect_uri,
AttributeError: 'OAuth2Token' object has no attribute 'redirect_uri'

私はメソッドgenerate_authorize_url()でredirect_uriを提供し、GoogleAPIコンソールで2つの「リダイレクトURI」を入力しました。

なぜredirect_uriが緩んでいるのですか?

解決策:@bossylobsterの回答を参照してください。


問題2 今、私はこの新しいアクセストークンを次のように保存したいと思います:

access_token_key = 'access_token_%s' % current_user.user_id()
gdata.gauth.ae_save(token, access_token_key)

これらの行はこの例外をスローします:

Traceback (most recent call last):
  File "[$PATH]/dev/outils/google_appengine/google/appengine/ext/webapp/_webapp25.py", line 701, in __call__
    handler.get(*groups)
  File "[$PATH]/dev/outils/google_appengine/google/appengine/ext/webapp/util.py", line 68, in check_login
    handler_method(self, *args)
  File "[$PATH]/dev/projets/xxx/main.py", line 89, in get
    gdata.gauth.ae_save(token, access_token_key)
  File "[$PATH]/dev/projets/xxx/gdata/gauth.py", line 1593, in ae_save
    return gdata.alt.app_engine.set_token(key_name, token_to_blob(token))
  File "[$PATH]/dev/projets/xxx/gdata/alt/app_engine.py", line 92, in set_token
    if Token(key_name=unique_key, t=token_str).put():
  File "[$PATH]/dev/outils/google_appengine/google/appengine/ext/db/__init__.py", line 973, in __init__
    prop.__set__(self, value)
  File "[$PATH]/dev/outils/google_appengine/google/appengine/ext/db/__init__.py", line 613, in __set__
    value = self.validate(value)
  File "[$PATH]/dev/outils/google_appengine/google/appengine/ext/db/__init__.py", line 2779, in validate
    (self.name, self.data_type.__name__, err))
BadValueError: Property t must be convertible to a Blob instance (Blob() argument should be str instance, not unicode) 

ただし、変更を加えてトークンを返すgdata.gauth.access_token呼び出し。gdata.gauth.upgrade_to_access_token

で試してみるとtoken_to_blob、この例外がありますUnsupportedTokenType: Unable to serialize token of type <type 'unicode'>

**新しいアクセストークンをどのように保存しますか?**

main.py:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app, login_required
from google.appengine.api import users

import gdata.gauth
import atom.http_core


SETTINGS = {
    'APP_NAME': 'xxx',
    'CLIENT_ID':'xxx.apps.googleusercontent.com',
    'CLIENT_SECRET':'xxx',
    'SCOPES': ['https://www.google.com/m8/feeds/', 'https://docs.google.com/feeds/', 'https://www.google.com/calendar/feeds/'],
    'USER_AGENT' : 'xxxs',
    'OAUTH2CALLBACK':'http://localhost:8080/oauth2callback'
    #'OAUTH2CALLBACK':'http://example.com/oauth2callback'
    }

class Home(webapp.RequestHandler):

    def get(self):
        """Home"""
        if users.get_current_user():
            self.redirect("/step1")
        else:
            self.response.out.write("<a href='/step1'>Sign in google</a><br />")

class Fetcher(webapp.RequestHandler):

    @login_required
    def get(self):
        """This handler is responsible for fetching an initial OAuth
        request token and redirecting the user to the approval page."""

        current_user = users.get_current_user()

        #create token
        token = gdata.gauth.OAuth2Token(client_id = SETTINGS['CLIENT_ID'],
                                        client_secret = SETTINGS['CLIENT_SECRET'],
                                        scope = ' '.join(SETTINGS['SCOPES']),
                                        user_agent = SETTINGS['USER_AGENT'])



        url = token.generate_authorize_url(redirect_uri = SETTINGS['OAUTH2CALLBACK'])
        #save token to datastore
        gdata.gauth.ae_save(token, current_user.user_id())

        message = """<a href="%s">
        Request token for the Google Documents Scope</a>"""

        self.response.out.write(message % url)
        self.response.out.write(" ; redirect uri : %s" % token.redirect_uri)

class RequestTokenCallback(webapp.RequestHandler):


    @login_required
    def get(self):
        """When the user grants access, they are redirected back to this
        handler where their authorized request token is exchanged for a
        long-lived access token."""

        current_user = users.get_current_user()

        #get token from callback uri
        url = atom.http_core.Uri.parse_uri(self.request.uri)

        # get token from datastore
        token = gdata.gauth.ae_load(current_user.user_id())
        # SOLUTION 1
        token.redirect_uri = SETTINGS['OAUTH2CALLBACK']

        if isinstance(token, gdata.gauth.OAuth2Token):
            if 'error' in url.query:
                pass
            else:
                token.get_access_token(url.query)

         gdata.gauth.ae_save(gdata.gauth.token_to_blob(token), "access_token_" + current_user.user_id())

def main():
    application = webapp.WSGIApplication([('/', Home),
                                          ('/step1', Fetcher),
                                          ('/oauth2callback', RequestTokenCallback)],
                                         debug = True)
    run_wsgi_app(application)

if __name__ == '__main__':
    main()

app.yaml:

application: xxx
version: 2
runtime: python
api_version: 1

handlers:

- url: .*
  script: main.py
4

1 に答える 1

0

を呼び出すときはAeLoad、 を見る必要がありますAeSave。呼び出されたソースコードに気付くでしょう。token_to_blob

ただし、 のソースtoken_to_blobは、redirect_uriは blob に保存されないため、保持して次のように呼び出す必要があります。

token = gdata.gauth.ae_load(current_user.user_id())
token.redirect_uri = SETTINGS['OAUTH2CALLBACK']

参考までに、別の関連記事を参照してください。

質問 2 への回答: トレースバックを読んでください:Blob()引数はstrではなくインスタンスである必要がありますunicode。ローカルで使用しているのバージョンはPython?

于 2012-05-08T18:19:36.490 に答える