1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Djangoで構築したWEBサーバに最低限のセキュリティ対策を施す ① ログイン認証

Posted at

#はじめに
本稿ではDjangoで構築したサーバに以下の最低限のセキュリティ対策を行う手順を解説します。(DjangoでWebアプリケーション構築済である前提とします。)

  • ログイン認証の追加
  • SSL対応 (記事作成中)

#ログイン用アプリケーションの作成
まずプロジェクト配下でログイン機能用のアプリケーションを作成する。

$ python manage.py startapp accounts

アプリケーション作成後のプロジェクト構成は以下。

sample_project
├── accounts <- ログイン用アプリケーション
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── urls.py
│   └── views.py
├── sample_app <- 固有アプリケーション
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── index.html
│   ├── urls.py
│   └── views.py
├── config
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

プロジェクト配下のsetting.pyとurls.pyにログイン用アプリケーション用の設定を追記。

setting.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'sample_app.apps.SampleAppConfig', # Custom App
    'accounts.apps.AccountsConfig',    # 追加
]
config/urls.py
urlpatterns = [
    path('admin/', admin.site.urls),
    path('sample_app/', include('sample_app.urls')), # Custom App
    path('', include('accounts.urls')),              # 追加 ログイン用
]

#ログイン用フォーム、ビュー、テンプレートの作成
以下、ログイン画面の部品をそれぞれ作成する。

  • ログイン用フォームの定義:forms.py
  • ログイン用ビューの定義:view.py
  • ログイン画面用テンプレート:login.html

フォームの定義はDjango標準クラスのAuthenticationFormを用いる。

forms.py
from django.contrib.auth.forms import AuthenticationForm

class LoginForm(AuthenticationForm):
    """ログインフォーム"""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        for field in self.fields.values():
            field.widget.attrs['class'] = 'form-control'
            field.widget.attrs['placeholder'] = field.label   

importしているクラスは以下。

クラス名 機能
LoginRequiredMixin ログインしたユーザだけ閲覧できるようにする
LoginView ログイン機能
LogoutView ログアウト機能
LogoutForm 上記で定義したログイン用フォーム
view.py
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import(LoginView, LogoutView)
from .forms import LoginForm

class Login(LoginView):
    """ログインページ"""
    form_class = LoginForm
    template_name = 'login.html'


class Logout(LoginRequiredMixin, LogoutView):
    """ログアウトページ"""
    template_name = 'login.html'
login.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>LOGIN</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <form action="" method="POST">
        {% csrf_token %}
        {% for field in form %}
            {{ field }}
        {% endfor %}
        {% for error in form.non_field_errors %}
            {{ error }}
        {% endfor %}
        <button type="submit">ログイン</button>
    </form>
</body>
</html>

フォーム、ビュー、テンプレート追加後のプロジェクト構成は以下。

sample_project
├── accounts <- ログイン用アプリケーション
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── login.html
│   ├── urls.py
│   └── views.py
├── sample_app <- 固有アプリケーション
│   ├── __init__.py
│   ├── admin.py
│   ├── apps.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── templates
│   │   └── index.html
│   ├── urls.py
│   └── views.py
├── config
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

ログイン用アプリケーションのurls.pyにURLとビューの紐づけを追記する。

accounts/urls.py
urlpatterns =[
    path('login/', views.Login.as_view(), name='login'),
]

#リダイレクトURLの設定
setting.pyに未ログイン時に表示されるURL、ログイン・ログアウト時のリダイレクトURLを設定する。

setting.py
LOGIN_URL = '/login' # ログインしていないときのリダイレクト先
LOGIN_REDIRECT_URL = '/sample_app/index' # ログイン後のリダイレクト先
LOGOUT_REDIRECT_URL = '/login' # ログアウト後のリダイレクト先

ログイン認証を追加するアプリケーションの設定

ログイン先のアプリケーションのビューにログイン必須設定を行う。
クラスベースのビューの場合、LoginRequiredMixinをimportして継承することでログイン必須となる。

sample_app/view.py
from django.contrib.auth.mixins import LoginRequiredMixin

class Test(LoginRequiredMixin, TemplateView):
    template_name = 'index.html'

メソッドベースのビューの場合、@login_requiredのアノテーションを付与することでログイン必須となる。

from django.shortcuts import render
from django.contrib.auth.decorators import login_required
 
@login_required 
def index(request):
    return render(request, 'index.html')

#ユーザーの作成
プロジェクト配下でユーザーを作成する。

$ python manage.py createsuperuser

#テスト
これでアプリケーションを起動してログインURLにアクセスするとログインフォームが表示されるはずなので、作成したユーザーのID/Passでログインできればログイン認証成功です。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?