引き続き、「作ればわかる! Google App Engine for Java プログラミング」本にてPythonを修行中。
前回PayPalを追加したので、今回はセッションの追加。
セッションに関しては不勉強なところもあるため、いわゆる徳丸本を参照しながら実装。
体系的に学ぶ 安全なWebアプリケーションの作り方 脆弱性が生まれる原理と対策の実践
- 作者: 徳丸浩
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2011/03/03
- メディア: 大型本
- 購入: 119人 クリック: 4,283回
- この商品を含むブログ (138件) を見る
■環境
- Google App Engine SDK for Python 1.7.1 - 2012-08-21
- webapp2 2.5.1
■Google App Engineで使えるセッション機構
本体に付属しているセッション機構は無い。
ただ、webapp2のwebapp2_extrasにはSessionsがあるため、そちらを利用する。
webapp2 - Sessions
なお、webapp時代には以下のようなライブラリがあったものの、webapp2時代では利用できない模様。
比較表で優れているとの記載あり。ただし、webappベースで作られていたようなので、webapp2の今では動かない。
参考:stackoverflow - gae-sessions equivalent for Python 2.7
もしgae-sessionsを使うならば、以下を参照のこと。
stackoverflow - How to use session on Google app engine
IACC開発ブログ - GAEでセッションを使ってみた by gae-sessions
Mere Mortals - How to use sessions on Google App Engine with Python and gae-sessions?
GitHubにコードはあったけれど、動かないとか書かれている。
■webapp2_extrasで、バックエンドにDatastoreを使うときの注意点
何も設定しないままだと、以下のログが出力される。
Traceback (most recent call last):
File "/base/python27_runtime/python27_lib/versions/third_party/webapp2-2.3/webapp2_extras/appengine/sessions_ndb.py", line 18, in
from ndb import model
ImportError: No module named ndb
そのため、以下の3パターンのいずれかで対応する。
1.app.yamlに追記するパターン (今回はこの方法を採用)
libraries: - name: webapp2 version: 2.5.1
「version: latest」としてもよいが、望みどおりのバージョンで動かなかったこともあったので、バージョンを具体的に指定した方が良いかと。
2.ndb.pyを追加するパターン
ndb.pyを追加する。SDK1.6.1 pre-releaseでは修正されていた模様だが、1.7.1では再発。
# -*- coding: utf-8 -*- from google.appengine.ext.ndb import model
3.sys.modulesに追加するパターン
セッション管理するプログラムに以下を追加する。
import sys from google.appengine.ext import ndb sys.modules['ndb'] = ndb
参考:stackoverflow - Import Error for User Model
■実装する箇所
自分でも忘れそうなため、メモ。
なお、以下の記事を参考に実装。
- webapp2公式 - Sessions
- The Aspiring Pythoness - How to Configure Different Session Backends in Webapp2
- devslog - 【GAE/Python2.7】webapp2のsessionを使う方法
- snaka gist - webapp2_extras の sessions を使う
import設定
セッションに必要な、以下の3つをimportする
from webapp2_extras import sessions from webapp2_extras import sessions_memcache from webapp2_extras import sessions_ndb
セッションを利用するためのベースクラスを作成する
バックエンドで使いたいものをsession内でアンコメントする
class BaseSessionHandler(webapp2.RequestHandler): def dispatch(self): self.session_store = sessions.get_store(request=self.request) try: webapp2.RequestHandler.dispatch(self) finally: self.session_store.save_sessions(self.response) @webapp2.cached_property def session(self): # 以下はmemcache時 #return self.session_store.get_session(backend='memcache') # 以下はCookie版 #return self.session_store.get_session(backend='securecookie') # Datastore版 #return self.session_store.get_session(backend='datastore')
セッションを使うクラスの親クラスを変更
前)
class CartPageHandler(webapp2.RequestHandler):
後)
class CartPageHandler(BaseSessionHandler):
出し入れ
入れる)
self.session['test'] = 'message'
出す)
session = self.session.get('test')
webapp2.WSGIApplicationに、configの設定を追加
なお、cookie_argsのsecureは、localhostの場合はhttpsが使えないために、Trueのままではセッションのテストがうまく動作しないことに注意。
config = {} config['webapp2_extras.sessions'] = { 'secret_key': 'my-secret-key', 'cookie_name' : 'my-session-name', 'cookie_args' : { 'max_age' : None, # Noneの場合、クライアント終了時にクッキー削除 'domain' : None, # 徳丸本(p218)より 'path' : '/', 'secure' : True, # セキュア属性、https接続なのでTrue 'httponly': True # 徳丸本(p219)より、ONにしておく }, 'backends': {'datastore': 'webapp2_extras.appengine.sessions_ndb.DatastoreSessionFactory', 'memcache': 'webapp2_extras.appengine.sessions_memcache.MemcacheSessionFactory', 'securecookie': 'webapp2_extras.sessions.SecureCookieSessionFactory', } } app = webapp2.WSGIApplication([(URL_START, CartPageHandler), (URL_PAYMENT + '*', PaymentPageHandler), (URL_CANCEL_REDIRECT + '.*', CancelHandler), (URL_CANCEL, CancelPageHandler), ], config=config, debug=debug)
app.yamlへの追記(webob)
現時点では解決しているかもしれないが、以下の記事に従い、IE対応。
The Aspiring Pythoness - Setting Cookie Expiration in WebApp2
libraries: - name: webob version: latest
セッション関連のエラー処理を追加
適宜追加。今回は子クラスで同じようなエラー処理を加えたため、親クラスに追加。
■その他
webapp2ドキュメントにおける、親クラスメソッドの呼出について
super()を使ったほうが良いとのこと。
stackoverflow - AttributeError: 'NoneType' object has no attribute 'route' and webapp2
webapp2のバックエンドについて
以下を見る限り、memcachedとndbのみ実装されている模様。
webapp-improved
NDBとHRDは併用できるのか?
今回の場合、記事データはHRD、セッションはNDBへと保存することになる。併用できるか分からなかったが、今のところは問題なく動作している。(ただし、このままで良いのかはわからない)