9.4 DjangoとReactでの実装

 Djangoは「9.2. ログインとセッション(認証と認可)」で説明した、ログイン認証やセッションの管理を行う機能を備えています。ここでは、Djangoのこれらの機能を使って、ログインしたユーザーのみがアプリケーションサービスを利用できるようにする方法を解説します。

9.4.1 認証のためのユーザーモデル

まずDjangoの認証機能を使うためのユーザーモデルが必要になりますので、django.contrib.auth.models.AbstractUserを継承したクラスを定義します。

基底クラスとなるAbstractUserは、元々以下のフィールドを持っています。

  • username:ユーザ名(ログインに使用する)
  • first_name : 名
  • last_name:姓
  • email :emailアドレス
  • is_staff:スタッフかどうかのフラグ
  • is_active:アクティブかどうかのフラグ
  • date_joined:登録された日時
  • password (AbstractBaseUserからの継承)
  • groups:ユーザーが所属するグループ
  • user_permissions:パーミッション

また、パスワードを文字列からハッシュ化して格納したり、emailアドレスのフォーマットをチェックしたりするするためのメソッドなどを備えています。

ユーザーモデルでは、これにアプリケーションで必要な独自のフィールドを追加設定します。特に追加するものがなければdjango.contrib.auth.models.Userを使うのが良いでしょう。

ここではgender(性別)のフィールドを追加してみます。さらに、基底クラスのフィールドで不要なものにはNoneを入れておきます。

9.4.2 ユーザーの登録機能の追加

 次にユーザーを登録する機能を作っておきます。(djangoのアドミニストレーション画面から登録することもできますが、ここでは登録機能のビューを作ってみます。)

ここではSignupView という名前のビューと、これが使うテンプレートとフォームを定義します。

フォーム

SignUpFormに、定義したユーザーモデルに対応するフォームを設定します。

Metaクラスを使って、対応するユーザーモデルと、モデルにあるフィールドのうち実際に入力をしてもらうものを設定します。また、新たに追加したgenderフィールドについてはフォームに設定を追加しておきます。(AbstractUserを使うとパスワード入力用のフィールドpassword1と確認用のpassword2が必要になりますので、これは定義しておきます)

テンプレート

ViewをGETで呼び出した時に表示される。以下の画面のテンプレートsignup.htmlを定義します。

テンプレートファイルは、以下のようにsettings.pyで定義した'TEMPLATES'の'DIRS'に記載したフォルダの下に配置します。

ビュー

最後にSignupViewを定義します。

  • getメソッドには、使用するフォーム(SiguUpForm)とテンプレート(signup.html)を指定します。
  • postメソッドでは、requestから入力されたフォームを取り出し、register_userでユーザーモデルインスタンスを作り保存し、ついでにauth_login()でログインを行っています。

9.4.3 ログイン機能の追加

django.contrib.auth.viewsが提供しているデフォルトのLoginViewを使います。

ユーザー名とパスワード文字列を入力することにより、認証を行い、バックエンド側でセッション情報を生成。cookieにセッションIDを入れて返送します。このビューがGETで呼ばれた時にログイン情報入力画面を表示するテンプレートをtemplatesフォルダの下の'registration/login.html'に置きます。

registration/login.html

テンプレートの構造は先ほどのsignup.htmlと同じです。

6.4.4 ログアウト機能の追加

django.contrib.auth.viewsで提供されているLoginViewを使います。LogoutViewが呼ばれると、djangoは保持していたセッション情報を廃棄します。こちらは特にテンプレートを用意する必要はありません。

6.4.5 システム設定

まず、backend/urls.pyにユーザー登録、ログイン、ログアウトのためのURLを設定します。

次にbackend/settings.pyに以下の情報を追加して、Djangoによる認証、ログイン、ログアウトの動作を設定します。

6.4.6 ログインしたユーザーのみにdjangoのサービスを許可する

ここまででログイン認証とセッション管理はできるようになりました。ここからはログインしているユーザーのみに対してサービスが有効になるようにアプリケーションプログラムを設定していきます。

ログインしているユーザーにのみサービスを有効にする方法は2通りあります。

Viewクラス単位での設定

genericビューのクラスのauthentication_classesとpermission_classesを設定します。

これにより、Viewクラスのメソッド全体に対し、セッション認証ができている場合にのみアクセスが許可されるようになります。

関数単位での設定

関数単位でデコレーターを使って許可設定を行う方法です。デコレータとは関数やクラスの前後に特定の処理を追加できる機能です。

関数の定義の前に、login_requiredデコレーターを設定しておくと、この関数post()はセッション認証ができている場合にのみアクセスを許可されます。

6.4.7 ログインしたユーザーのみにReactアプリへのアクセスを許可する

 6.4.6の設定でdjangoのREST APIへのアクセス許可は設定することができましたが、これだけだと、staticディレクトリに置かれているReactを使ったフロントエンドアプリケーションのファイルはそのままアクセスできてしまいます。djangoのアクセス制限の機能を使うために、少しトリックを使います。

Djangoのビュー関数index_view()を定義し、これの中で「テンプレート」としてREACTアプリケーションの呼び出しを含むindex.htmlを表示します。index_view()に対しlogin_requiredデコレーターを指定することで、ログインしているユーザーのみに対してのみアプリケーションの表示がされるようになります。

このプログラムからindex.htmlを正しく読み込むために、REACTでビルドされたファイルのうち、index.htmlsettings.pyTEMPLATEDIRで定義したディレクトリ(ここではtemplates)に移動しておきます。

これまではREACTアプリケーション関連のファイルへのルーティングは、staticディレクトリをmy_appと紐づけることで行なっていましたが、これをdjangoのurlpatternsで紐づけるようにします。

まず、settings.pySTATIC_URLをmy_appとは違う名称に変更します。

次にurls.pyurlpatternsにエントリーを追加します。

ちなみにurlpatternsの2つ目のエントリーにあるserveというviewはstaticディレクトリにリダイレクトを行う機能を持っています。