認証
久々のDjangoネタ。
magic-removal版は更新が激しくなかなか落ち着きませんが・・・。
Djangoには組み込みで認証のフレームワークがついています。
http://ymasuda.jp/python/django/docs/authentication.html
にも書かれていますが。
from django.contrib.auth.decorators import login_required def my_view(request): # ... my_view = login_required(my_view)
とします。
ユーザがログインしていなければ, "/accounts/login/" にリダイレクトします。
このとき,現在のクエリの絶対 URL を next に入れ,例えば /accounts/login/?next=/polls/3/ のようにリダイレクトします。
ここまではドキュメントにも書かれています。
で実際ログイン処理はどうすればいいのさ?って話です。
上記でも書きましたが"/accounts/login/"にログインフォームを設定するわけですがせっかくなのでログインフォーム作成、認証もDjangoにやらせましょう。
url.py
from django.conf.urls.defaults import * from django.conf import settings urlpatterns = patterns('', # Example: (r'^/?accounts/login/$', 'django.contrib.auth.views.login'), )
settings.py
・・・・・ INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.markup', ・・・ ) ・・・・
のように認証アプリ"django.contrib.auth"をインストールします。
"accounts/login/"にインストールしたcontribのviewを指定します。
そうすると"/accounts/login/"('django.contrib.auth.views.login')は"registration/login"ページを表示しようとします。
django.contrib.auth.views.loginの中身は以下
def login(request): "Displays the login form and handles the login action." manipulator = AuthenticationForm(request) redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '') if request.POST: errors = manipulator.get_validation_errors(request.POST) if not errors: # Light security check -- make sure redirect_to isn't garbage. if not redirect_to or '://' in redirect_to or ' ' in redirect_to: redirect_to = '/accounts/profile/' request.session[SESSION_KEY] = manipulator.get_user_id() request.session.delete_test_cookie() return HttpResponseRedirect(redirect_to) else: errors = {} request.session.set_test_cookie() return render_to_response('registration/login', { 'form': forms.FormWrapper(manipulator, request.POST, errors), REDIRECT_FIELD_NAME: redirect_to, 'site_name': Site.objects.get_current().name, }, context_instance=RequestContext(request))
Getの場合
return render_to_response('registration/login', { 'form': forms.FormWrapper(manipulator, request.POST, errors), REDIRECT_FIELD_NAME: redirect_to, 'site_name': Site.objects.get_current().name, }, context_instance=RequestContext(request))
とformWrapper、元々アクセスしたいURL(redirect_to)も使えるようになります。
これを踏まえ自分のAPPのテンプレートのDirに"registration/login.html"を作成します。
registration/login.htmlの例
{% extends "base" %} {% block content %} {% if form.error_dict %} <p class="errornote"> ログイン、パスワードが正しくありません。 </p> {% endif %} <h3>ログイン</h3> <form method="post" action="/accounts/login/?next={{ next }}"> <p> <label for="id_username" />ユーザ名</label>{{form.username}}</p> <p> <label for="id_password" />パスワード</label>{{form.password}}</p> <input type="submit" /> </form> {% endblock %}
nextにはログイン後リダイレクトするURLが入ります。
つまり最初にアクセスしようとした絶対 URL が next に入ります。
これで認証が通れば今後は認証なしでアクセスできます。
(デフォルトなので有効期間は2週間)
うくく。