2009.07.31
Python + Django でURLにセッションを組み込む(携帯で使えるはず)
Python界では有名なWEBアプリケーションフレームワークであるDjango
いろいろと高機能なんですが、ひとつだけ困ったことが。
それは「セッションがクッキーベース」なこと。
確かにこの方がセキュアですし、おススメなんですが、
携帯向けにECサイトを作成しようとすると必ずネックになるのが
クッキーが使えない!ということ。(一部の端末では対応していますが)
そこでDjangoでセッションキー(セッションID)をURL(またはPOST/GET)に
埋め込む方法を考えてみました。
まずDjangoでクッキーが使えないとどうなるでしょうか?
クッキーが使えない
↓
クッキーでセッションキーを読み書きできない
↓
セッションキーをキーとしてサーバに保存されているセッション情報を読み書きできない
↓
セッション情報に保存されている認証情報を利用できない
↓
認証が行えず、会員制サイトなどが構築できない。
・・・となり、結構根が深い訳です。
これでは携帯でECサイト構築なんてできないですよね。。
そこで無いものは作ってしまえぃ、ということで、
Djangoのセッションと認証周りをソースレベルで調べてみました。
ソースについての詳細は省きますが、
結論としては意外と簡単にできるんです!
以下にやり方を書いておきます。
(1)
一番コアな部分は実は1つだけ。
views.pyに
from django.conf import settings
engine = __import__(settings.SESSION_ENGINE, {}, {}, [''])
def session_url(original):
def decorated(request, *args, **keywords):
request.session = engine.SessionStore(request.GET['session_key'] or request.POST['session_key'])
return original(request, *args, **keywords)
return decorated
を追加してください。
ここに全てが詰まっています。
あとはこの”session_url”をデコレータとして使います。
(2)
このデコレータの使い方は以下のようになります。
@session_url
@login_required
def index(request):
return render_to_response(’index.html’, {’session’:request.session})
ここで”@login_required”は認証済みユーザーだけが利用できるようにするためのデコレータで
Djangoに標準で用意されています。(django.contrib.auth.decorators.login_required)
このデコレートされたものをさらに先ほどの”@session_url”でデコレートしています。
この順番は大事ですので気をつけてください。
(3)
あとはログイン時にGETパラメータとしてセッションキーを渡してやればいいはずです。
def login(request):
if request.method == ‘POST’:
user = django.contrib.auth.authenticate(username=request.POST['name'], password=request.POST['pass'])
django.contrib.auth.login(request, user)
return HttpResponseRedirect(’/index/?session_key=%s’ % (request.session.session_key))
else:
return render_to_response(’login.html’, {})
これで”request.session”を従来通りの方法で使用できます。
お試しください。
(もちろん各ページのリンクやフォームでセッションキーを埋め込むのをお忘れなく!)
発展的内容
(1)
さらに今度はGET/POSTではなく、URLのパス部分に埋め込んでみます。
(http://aaa.com/[session_key]/index/ の形での使用を可能にします)
これも簡単で、”session_url”デコレータで
def decorated(request, *args, **keywords):
request.session = engine.SessionStore(request.GET['session_key'] or request.POST['session_key'])
↓
def decorated(request, session_key, *args, **keywords):
request.session = engine.SessionStore(session_key)
としてください。
(2)
次にログイン部分は
return HttpResponseRedirect(’/index/?session_key=%s’ % (request.session.session_key))
↓
return HttpResponseRedirect(’/%s/index/’ % (request.session.session_key))
としてやります。
(3)
URLからセッションキーを取得するので、urls.pyを変更します。
また、URLのパスが変わるので何もしないと元のurls.pyが使えなくなってしまいます。
そこで例えば
(r’^(?P
のようにしてやることで、”session_key”を渡しつつ、同時に元のurls.pyを活かして使うことが可能になります。
これでURLのパスに埋め込んでも使えるはずです。
Trackback URL
Comment & Trackback
Comment feed
Comment