【django】アクセス制限:ログインを必須にする(サイト全体・ページ毎)

時計 2021.04.13 / 時計

【django】アクセス制限:ログインを必須にする(サイト全体・ページ毎)

本記事では、PythonのWebフレームワークdjangoによるWebアプリケーションで、ログイン必須にする方法について解説していきます。

Webアプリケーションにログイン認証機能を組み込んでいるならば、ログインの有無によるアクセス制限を設けると、より一層使い勝手の良いWebアプリケーションになります。

例えば、会員のみが閲覧可能な会員専用ページを作成するなどが可能になります。

ログイン認証機能の組み込み方法は、以下記事をご参照ください。

アクセス制限(ログイン必須)は、サイト全体で一括して設定することもできますし、ページ毎(ビュー毎)で設定することも可能です。

本記事を通して以下の知識を学べます。

学べる知識
  • アクセス制限(ログイン必須)について
  • ログイン必須をページ毎に設定する方法
  • ログイン必須をサイト全体で一括設定する方法

アクセス制限;ログイン必須とは

本記事で言っているログイン必須とは、
Webアプリケーションのページ(URL)にアクセスした際に、ログインしていなかった場合、ログインページに自動的にリダイレクトすることを言います。

このログインを必須にする機能は、djangoに初めから備わっている仕組みを使うことで、簡単に実装することができます。

以下でログイン必須にする機能の実装方法を解説していきます。

ログイン必須にする方法

Webアプリケーションをログイン必須にする方法は、大きく分けて以下2つあります。

  • ページ毎にログイン必須にする
  • サイト全体を一括でログイン必須にする

上記の2つは、それぞれ仕組みが異なります。
ご自身のWebアプリケーションに合う方法で組み込んでみてください。

ページ毎にログイン必須にする

特定のページに対して、ページ閲覧をログイン必須にする場合は、django.contrib.authを使用します。

django.contrib.authアプリケーションは、ログイン認証機能を組み込む際にも使いましたが、今回のログイン必須にする仕組みでも使います。

ページ毎にログイン必須にする方法は、クラスベースビューと関数ベースビューで異なります。

クラスベースビュー:LoginRequiredMixin

クラスベースビューの場合は、
django.contrib.auth.mixinsのLoginRequiredMixinを継承することで、このクラスベースビューの処理がログイン必須になります。

from django.contrib.auth.mixins import LoginRequiredMixin

class IndexView(TemplateView,LoginRequiredMixin):
    template_name = "five/index.html"

LoginRequiredMixinを継承するだけなので、非常に簡単にログイン必須にできます。

しかしログイン必須にしたいクラスベースビューすべてにLoginRequiredMixinを継承させる必要があるので、ビューの数が多い場合は少し面倒になります。

関数ベースビュー:login_required

関数ベースビューの場合は、
django.contrib.auth. decoratorsのlogin_requiredのデコレーターをビュー関数の直前に記入することで、関数ビューの処理がログイン必須になります。

from django.contrib.auth.decorators import login_required

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

@login_requiredデコレーターは、アクセスしたユーザーがログインしていない場合、settings.pyのLOGIN_URL にリダイレクトします。

ユーザーがログインしていれば、そのまま関数ビューを処理します。

@login_requiredデコレーターも、ログインを必須にさせた関数ビューすべてに記入する必要があります。
そのためビューの数が多い場合は手間がかかります。

サイト全体を一括でログイン必須にする

すべてのビューでログイン必須にする場合は、一括でログイン必須にする方法を使用しましょう。

一括でサイトをログイン必須にするにはミドルウェア(Middleware)を使用します。

ミドルウェアによるログイン必須にするには、以下2つの方法があります。

  1. MiddlewareMixinを使用
  2. GlobalLoginRequiredMiddlewareを使用

各ミドルウェアの作成・使用方法を以下で解説します。

MiddlewareMixin

アプリケーションフォルダ直下(urls.pyやviews.pyの階層)にmiddlewareフォルダを作成します。

次に作成したmiddlewareフォルダ内にお好きな名前のpyファイル(ここではauth.pyとする)を作成し、以下のように記述します。

# middleware.auth.py
from django.utils.deprecation import MiddlewareMixin
from django.http import HttpResponseRedirect

class AuthMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        if request.path != '/login/' and not request.user.is_authenticated:
            return HttpResponseRedirect('/login/')
        return response

リクエストされたURLがloginの場合と、ユーザーがログインしている場合を除いて、loginにリダイレクトするよう記述されています。

ログインしているかどうかは、request.user.is_authenticatedで判別しています。

ミドルウェア(auth.py)を作成しましたら、settings.pyにそのミドルウェアを追加します。

# settings.py
# アプリケーション名がfiveの場合
MIDDLEWARE = [
    'five.middleware.auth.authMiddleware',
]

これにより、Webアプリケーション全体がログイン必須になります。

まとめるとMiddlewareMixinによるログイン必須の方法は以下の流れで行います。

  1. middlewareフォルダを作成
  2. ミドルウェアpyファイルを作成
  3. settings.pyにミドルウェアを追加

GlobalLoginRequiredMiddleware

GlobalLoginRequiredMiddlewareモジュールを使用するために、pipを使用してdjango-glrmをインストールします。

pip django-glrm

次に以下のようにsettings.pyにミドルウェアを追加します。

# settings.py
MIDDLEWARE = [
    'global_login_required.GlobalLoginRequiredMiddleware',
]

最後にsettings.pyにPUBLIC_PATHSを追加し、ログインを必須にしないURLを指定します。

PUBLIC_PATHS = [
	'/login/',
]

これにより、上記で指定したURL以外はログイン必須となります。

まとめ

本記事「【django】アクセス制限:ログインを必須にする(サイト全体・ページ毎)」はいかがでしたか。

djangoでは、ログインを必須にするのは非常に簡単でしたね。

特別な記述をする必要なく、ログイン必須機能をWebアプリケーションに組み込めますので、ぜひご自身のサイトに組み込んでみてください。