Django ログイン認証 入門

2019年11月25日

Djangoにあらかじめ備わっている(ビルドインされた)認証機能とUserモデルを利用して、ログイン画面(ログイン機能の流れ)を構築してみます。

 

Djangoには、ログイン・ログアウト・パスワード変更/リセット等の認証関連の機能、すなわち認証のビュー(Authentication Views)があらかじめビルドインされています(Djangoのビューは他のフレームワークおけるコントローラーのことです)。本記事ではこのうちのログイン・ログアウトのビューを利用してみます。

 

 

Userモデルについて


 

認証のビューの説明の前に、ログイン時のユーザー名とパスワードで利用するUserモデルについての概要を説明します。DjangoにはすでにUserモデルが備わっています。このUserモデルを利用するパターンとしては「既存のUserモデルを拡張する」場合と「カスタムのUser モデルを置き換える」場合とに分けられ、主に以下4つのパターンに分けられます。(Django の認証方法のカスタマイズ 参照)

 

 「既存のUserモデルを拡張する」

 1. プロキシモデル

 2. OneToOneField

「カスタムのUser モデルを置き換える」

 3. AbstractUser

 4. AbstractBaseUser

 

django ドキュメントでは将来的にカスタマイズする可能性を考慮し「デフォルトの User で十分である場合でも、カスタムユーザーモデルを作成することを強く推奨」しています。

 

AbstractUserはUserクラスを継承しフィールド等を追加し上書きする場合に、AbstractBaseUserは認証機能は継承していますがフィールド等はすべて用意する場合に利用します。本記事ではこれらの詳しい説明はしませんが、AbstractUserを利用してカスタムのUserモデルを作成し話を進めていきます。

 

 

実装


 

本記事では4つの画面を用意して、下記イラストのような画面遷移を構築していきます。また、もしログインしている状態でトップ画面に訪れると「ログイン」のリンク部分が「ログアウト」になっており、ログインしていない状態でホーム画面に訪れるとログインフォーム画面へとリダイレクトされるようにします。

 

 

 

 

以降login_projectプロジェクト、myappアプリケーションを作成していることを前提とします。

 

まずはカスタマイズしたUserモデルを用意します。

 

myapp/models.py

AbstractUserを継承してCustomUserという名前のクラスを作成しています。これがカスタムのUserモデルとなります。既存のUserモデルにageフィールドを追加しています。

 

次にアプリケーションディレクトリ内のadmin.pyを編集します。下記の記述をすることによって管理サイト内(http://localhost:8000/admin/)でカスタマイズしたUserモデルを編集できるようになります。

 

myapp/admin.py

UserAdminを継承してCustomUserAdminサブクラスを作成しています。そしてfieldsets属性を利用することで、管理サイトのユーザー編集画面においてカスタムとして追加した「Age」が登録できるようになります(ModelAdmin.fieldsets 参照)。

 

 

 

カスタムのUserモデルを利用する場合、settings.pyに「AUTH_USER_MODEL」の項目を追記します。この記述は基本的にマイグレーションを実行する前におこなって下さい(カスタムの User モデルを置き換える 参照)。

 

login_project/settings.py

 

AUTH_USER_MODELの設定後に、マイグレーションファイルを作成し実行します。

 

管理者ユーザー(super user)を作成します。これで「http://localhost:8000/admin/」から管理サイトにログインすることができます。

 

 

認証のビューとテンプレート


 

プロジェクト配下のurls.pyに、下記のようにdjango.contrib.auth.urlsをインクルードすることによって、ビルドインされた認証のビューを利用できるようになります。ただしそれぞれのビューのテンプレートは作成する必要があります

 

login_project/urls.py

ビルドインされた認証のビューに対応するURLもデフォルトで用意されています。とりわけ本記事で利用するログインおよびログアウトに対応するデフォルトのURLは下記のようになります(他の認証のビューのURLは認証のView を参照)。pathの第1引数にmyapp/と指定しているので、ログイン画面のURLはmyapp/login/、ログアウト画面はmyapp/logout/となります。
詳しくは後述しますが、django.contrib.auth.urlsをインポートするだけで、templates/registration/以下に配置されたlogin.htmlおよびlogged_out.htmlという名前のテンプレートが、それぞれ上記URLにおいて自動的に表示されるようになります。またmyapp/urls.pyで特にloginおよびlogoutに関するビューを記述する必要もありません。

 

myapp/urls.py

上述したように「login_project/urls.py」において「django.contrib.auth.urls」をインポートしていれば、特にpathで「login/」や「logout/」の記述をしていなくてもデフォルトのURLに対応したビューが作動します。上記コードは認証のビューではないトップ画面(index)とホーム画面(home)の記述です。

 

myapp/views.py

9行目

login_required()デコレータを設定すると、ログイン状態でない場合に訪れると、任意のページへとリダイレクトさせることができます。リダイレクト先の画面はsettings.pyの「LOGIN_URL」で指定します(後述)。

 

クラスベースのビューの場合は、LoginRequiredMixinを利用します。

LoginRequired mixin を参照)

 

 

次にイラストで説明しているトップ(index)・ログイン・ホーム・ログアウトの4つの画面のテンプレートを下記のような階層で用意します。認証のビューのテンプレートは「templates/registration/」以下に配置する必要があります。

 

この際に、settings.pyのINSTALLED_APPSに設定したアプリケーション名(本記事ではmyapp)がdjango.contrib.adminよりも上に記述されているかを確認して下さい。もし下に記述している場合、ログアウト画面のlogged_out.htmlテンプレートが管理サイト(admin)側のテンプレートを利用されてしまいおかしな画面遷移となってしまいます。

why is logged_out.html not overriding in django registration? 参照

 

myapp/templates/myapp/index.html

 

myapp/templates/myapp/home.html

 

myapp/templates/registration/login.html

 

myapp/templates/registration/logged_out.html

 

 

最後にsettings.pyに、未ログイン状態でのリダイレクト先(LOGIN_URL)と、ログイン認証後のリダイレクト先(LOGIN_REDIRECT_URL)の設定を追記します。

 

login_project/settings.py

 

上記までの説明ではログアウト時の遷移先としてlogged_out.htmlテンプレートを用意しmyapp/logout/にリダイレクトさせていますが、もし「LOGOUT_REDIRECT_URL」を下記のように設定すると、ログアウト後の遷移先はトップ画面となります。

 

 

 

参照ページ


 

django ドキュメント

Django の認証方法のカスタマイズ

 

 

 

LINEで送る
Pocket

Copyright © 2019 思考の葉 All Rights Reserved.  プライバシーポリシー