webapp2のセッション機能を使ってみました
先日の記事で書いていたセッションのコードをwebapp2のセッション機能を使って書きなおしてみました。
コードはサンプルのものと全く同じです。
class BaseHandler(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): return self.session_store.get_session()
でセッションに対応したリクエストハンドラーを定義し、webapp2.RequestHandlerの代わりにこれを継承して応答用のクラスを作成すれば
# 値をセット self.session['foo'] = 'bar' # 値を取得 foo = self.session.get('foo')
という方法で値を読み書きすることができます。
前回のコードではセッション用のIDを都度
# 値をセット self.response.set_cookie('sessionID', new_sessionID, max_age=300) # 値を取得 sessionID = self.request.cookies.get('sessionID')
という方法でcookieに保存していましたがこの部分をwebapp2の機能を使った保存方法で置き換えました。
ただし書いてみて分かったのですが今回のコードではセッション機能を利用してcookieに保存しているのはランダムに生成したセッション用のIDのみなので
new_sessionID = binascii.hexlify(os.urandom(8))
で推測できないよう生成したIDを秘密鍵を使って更に暗号化してcookieに保存するという二度手間になっているだけなのでwebapp2のセッションを使用する意味がないと思います。(^_^;)
サーバ側コード(ブラウザ側は前回のものと同じ)
# coding: utf-8 import webapp2 import cgi import os import binascii import jinja2 import json from google.appengine.ext import db from webapp2_extras import sessions jinja_environment = jinja2.Environment( loader=jinja2.FileSystemLoader(os.path.dirname(__file__))) config = {} config['webapp2_extras.sessions'] = { 'secret_key': 'abcdefg',#秘密鍵 'session_max_age': 330 } class UserProfile(db.Model): sessionID = db.StringProperty() name = db.StringProperty() words = db.StringListProperty() date = db.DateTimeProperty(auto_now_add=True) class BaseHandler(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): return self.session_store.get_session() class MainPage(BaseHandler): def get(self): sessionID = self.session.get('sessionID') if not sessionID: new_sessionID = binascii.hexlify(os.urandom(8)) session = UserProfile(sessionID=new_sessionID) session.name = 'GUEST' session.words = [] session.put() template = jinja_environment.get_template('sessiontest2.html') self.response.headers['Content-Type'] = 'text/html;charset=utf-8' if not sessionID: self.session['sessionID'] = new_sessionID self.response.out.write(template.render()) def post(self): self.get() class JsonData(BaseHandler): """ページのJavascriptからリクエストを受けてJSONを送る """ @staticmethod def _session_check(sessionID): """ セッションIDがすでにデータストアに登録されているか確認し Queryを返す """ sessions = (UserProfile .all() .filter('sessionID =', sessionID) ) return sessions def post(self): sessionID = self.session.get('sessionID') if not sessionID: raise Exception('Session Error') return session = self._session_check(sessionID)[0] session.name = (cgi.escape(self.request.get('newUserName')) or session.name) if self.request.get('newWord'): session.words.append(cgi.escape(self.request.get('newWord'))) session.put() json_to_send = {'username': session.name, 'words': session.words} self.response.headers['Content-Type'] = 'application/json' self.response.out.write(json.dumps(json_to_send)) app = webapp2.WSGIApplication([('/', MainPage), ('/data', JsonData)], debug=True, config=config)