yanbe.diff このページをアンテナに追加 RSSフィード

2008-08-20

Google App Engine上でmixi OpenIDを使ってユーザ認証をするサンプルコード

15:34 |  Google App Engine上でmixi OpenIDを使ってユーザ認証をするサンプルコード - yanbe.diff を含むブックマーク はてなブックマーク -  Google App Engine上でmixi OpenIDを使ってユーザ認証をするサンプルコード - yanbe.diff  Google App Engine上でmixi OpenIDを使ってユーザ認証をするサンプルコード - yanbe.diff のブックマークコメント

追記

下記の方法はローカル環境(dev_appserver.py)では動作するものの,Google App EngineのProduction Serverにアップロードすると動かないそうです.これはGoogle App Engineの不具合で今後解決される見通しだそうです.

詳細:mixi openid - Google-App-Engine-Japan | Google グループ

追記2

nox氏により上記問題の暫定的な回避方法が公開されました.

概要

Google App Engine上でmixi OpenIDを使ってユーザ認証をするまでの手順とサンプルコードを以下に紹介します.

前準備

--- openid/fetchers.py	2008-08-21 15:03:40.000000000 +0900
+++ openid/fetchers.py.new	2008-08-21 15:10:22.000000000 +0900
@@ -11,6 +11,7 @@
 import time
 import cStringIO
 import sys
+import os
 
 import openid
 import openid.urinorm
@@ -29,6 +30,11 @@
 except ImportError:
     pycurl = None
 
+try:
+    from google.appengine.api import urlfetch
+except ImportError, e:
+    urlfetch = None
+
 USER_AGENT = "python-openid/%s (%s)" % (openid.__version__, sys.platform)
 MAX_RESPONSE_KB = 1024
 
@@ -45,7 +51,9 @@
     """Create a default HTTP fetcher instance
 
     prefers Curl to urllib2."""
-    if pycurl is None:
+    if urlfetch is not None:
+      fetcher = UrlfetchFetcher()
+    elif pycurl is None:
         fetcher = Urllib2Fetcher()
     else:
         fetcher = CurlHTTPFetcher()
@@ -228,6 +236,40 @@
 
         return resp
 
+class UrlfetchFetcher(HTTPFetcher):
+    """An C{L{HTTPFetcher}} that uses google.appengine.api.urlfetch.
+    """
+
+    urlopen = staticmethod(urlfetch.fetch)
+
+    def fetch(self, url, body=None, headers=None):
+        if not _allowedURL(url):
+            raise ValueError('Bad URL scheme: %r' % (url,))
+
+        if headers is None:
+            headers = {}
+
+        headers.setdefault(
+            'User-Agent',
+            "AppEngine-Google; (+http://code.google.com/appengine)")
+        headers.setdefault(
+            'Range',
+            '0-%s' % (1024*MAX_RESPONSE_KB,))
+
+        f = self.urlopen(url, payload=body, headers=headers)
+
+        return self._makeResponse(f)
+
+    def _makeResponse(self, urlfetch_response):
+        resp = HTTPResponse()
+        resp.body = urlfetch_response.content
+        resp.final_url = \
+            'http://'+os.environ['SERVER_NAME']+os.environ['PATH_INFO']
+        resp.headers = dict(urlfetch_response.headers.items())
+        resp.status = urlfetch_response.status_code
+        return resp
+
+
 class HTTPError(HTTPFetchingError):
     """
     This exception is raised by the C{L{CurlHTTPFetcher}} when it

サンプルコード

上記パッチを当てた前提で,Google App Enginemixi OpenIDを使って認証するサンプルコードは以下のような感じになる.http://localhost:8080/loginにアクセスすると,mixiOpenID認証確認画面にリダイレクトされる.この画面で「今回は同意する」ボタンを押すと,認証情報やニックネームがパラメータに含まれた状態でhttp://localhost:8080/login2にコールバックされる.

import wsgiref.handlers

from google.appengine.api import urlfetch
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template

from openid.consumer.consumer import Consumer
from openid.store.memstore import MemoryStore
from openid.extensions.sreg import SRegRequest

HOST = 'localhost:8080'

class LoginPage(webapp.RequestHandler):
  def get(self):
    session = {}
    store = MemoryStore()
    consumer = Consumer(session, store)
    request = consumer.begin('https://mixi.jp')
    sreg_request = SRegRequest(['nickname'])
    request.addExtension(sreg_request)
    urlroot = 'http://%s' % HOST
    urlredirect = request.redirectURL(urlroot, urlroot+'/login2',
        immediate=True)
    self.redirect(urlredirect)

class LoginPage2(webapp.RequestHandler):
  def get(self):
    if self.request.get('openid.mode') == 'setup_needed':
      user_setup_url = self.request.get('openid.user_setup_url')
      self.redirect(user_setup_url)
    else:
      print 'Content-type: text/plain\n'
      for k, v in self.request.GET.iteritems():
        print '%s: %s' % (k, v)

def main():
  url_handler_mapping = []
  url_handler_mapping.append((r'/login', LoginPage))
  url_handler_mapping.append((r'/login2', LoginPage2))

  application = webapp.WSGIApplication(url_handler_mapping, debug=True)

  wsgiref.handlers.CGIHandler().run(application)

if __name__ == '__main__':
  main()

ikuyironikuyiron2008/08/28 04:55HTMLによるリダイレクトを使うことでとりあえず動くようです。
http://mixi-openid.appspot.com/

y_yanbey_yanbe2008/08/28 09:31なるほど,HTMLによるリダイレクトを使うことで,Google App Engineに長いURLのリクエストを
処理させないようにすればいいのですね.参考になりました.

RoberscievaRoberscieva2017/05/09 13:53Cheap Viagra Online Canadian Pharmacy <a href=http://byuvaigranonile.com>viagra</a> Buy Tetracycline 500 Mg For Dogs 79 Find Isotretinoin Legally Tablet Bentyl 20mg In Internet

KennPhydayKennPhyday2017/06/20 06:28Sildenafil For Sale <a href=http://kamagra-online-buy.kamagpills.com>Kamagra Online Buy</a> Viagra Boisson Viagra In Holland Legal Kaufen <a href=http://priligy-90mg.priliorder.com>Priligy 90mg</a> Zithromax Online Overnight

トラックバック - http://subtech.g.hatena.ne.jp/y_yanbe/20080820