【Django】サイトを一括でログイン必須にさせる方法

django-loginrequiredmiddleware-title CODE

Djangoアプリケーションを簡単にログイン必須にする方法をまとめました。

ログイン必須とは、ログインせずにアプリケーション内のURLに遷移しようとした場合に、自動的にログインページにリダイレクトされる仕様ということです。

 

なお、この記事で使うPython・Django・django-axesのバージョンは以下のとおりです。

Python 3.7
Django 2.1.7
django-axes 5.0.12

 

王道のdjango.contrib.authを使用する方法

まずはネットによく紹介されているログイン必須の方法です。

・クラスベースビューの場合

from django.contrib.auth.mixins import LoginRequiredMixin

class View(TemplateView,LoginRequiredMixin):
    template_name = "template/index.html"
 LoginRequiredMixin を継承するだけでこのクラスに遷移する場合はログインが必要になります。

・関数ベースビューの場合

from django.contrib.auth.decorators import login_required

@login_required
def View(request):
  return render(request,"template/index.html")

関数ベースの場合も @login_required のデコレーターを利用すれば完了です。

 

しかし、この2つの場合はログイン必須にさせたい全ビューに書く必要があり、手間がかかります。

デコレーター・mixinを書き忘れた場合のことを考えると、この方法は適しているとは言えません。

 

ミドルウェアを使用して一括適用

そこで、リクエストを受けた段階でログイン済みか判定するミドルウェアを使用する方法をおススメします。

 

1. アプリ名/middleware/ 配下に適当な名前のpythonファイルを作り、以下を記述。

from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponseRedirect

class LoginRequiredMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        if request.path != '/login/' and not request.user.is_authenticated:
            return HttpResponseRedirect('/login/')
        return response
 request.user.is_authenticated でログインしているか判断し、リクエストのURLが  login の場合は処理しない。

2.settings.pyに作成したミドルウェアを追加。

MIDDLEWARE = [
    'アプリ名.middleware.ファイル名.LoginRequiredMiddleware',
]

 

これでログインページ以外の全ページがログイン必須になりました。

しかし、この方法だとログイン必須にさせたいページが増えるにつれ、if文が長くなっていくのでソースが煩雑になります。

 

GlobalLoginRequiredMiddlewareを使用

そこで便利なモジュールが、 GlobalLoginRequiredMiddleware です。

1.モジュールを使用するために  django-glrm をインストールします。

pip install django-glrm

 

2.ミドルウェアに global_login_required.GlobalLoginRequiredMiddleware を追加します。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    ...
    'global_login_required.GlobalLoginRequiredMiddleware',   # ←追加
]

 

3.ログインをしなくてもよいページのURLを settings.py に追加します。

PUBLIC_PATHS = [
	'/login/',  # ディレクトリごと除外することも可能
]

これでloginページ以外はログインが必須になりました。

 

ちなみに、  @login_not_required を使用してビューごとに指定することも可能です。