https://qiita.com/t-iguchi/items/54424f619829a6d135fc


Python + Djangoで独自のユーザ認証を実装する

この記事は最終更新日から1年以上が経過しています。

Djangoの認証機能を利用して簡単に認証機能を実装してみます

環境:
OS: Windows10 Home 64bit
Python 3.6.5
Django 2.0.6

Python + Djangoのプロジェクト作成でプロジェクトを作成します

1.migrate

python manage.py migrateを実行して、認証系のテーブルを作成します。

cmd.prompt
(venv) C:\data\python\work\myproject>python manage.py migrate

2.管理ユーザを作成する

管理ユーザを作成します。このユーザで認証を行うことになります。

cmd.prompt
python manage.py createsuperuser
Username (leave blank to use 'papa'): django
Email address: django@localhost
Password:
Password (again):
Superuser created successfully.

3.アプリケーションの構成

完成後のアプリケーションの構成は以下のとおりです
JQuery, Bootstrap4を使いますので、ダウンロードして配置しておきます

C:\data\python\work\myproject
├─accounts・・・・(1)
│  │  admin.py
│  │  apps.py
│  │  models.py
│  │  tests.py
│  │  urls.py・・・・(2)
│  │  views.py・・・・(3)
│  │  __init__.py
│  │  
│  ├─migrations
・・・
│  │          
│  └─__pycache__
・・・
├─myproject
│  │  settings.py・・・(8)
│  │  urls.py・・・・・(9)
│  │  wsgi.py
│  │  __init__.py
│  │  
│  └─__pycache__
・・・
├─static
│  ├─css
│  │      bootstrap.min.css
│  │      bootstrap.min.css.map
│  │      style.css・・・・(4)
│  └─js
│         bootstrap.bundle.min.js
│         jquery-3.3.1.min.js
└─templates
    ├─accounts
    │      top.html・・・・(5)
    ├─commons
    │      base.html・・・・(6)
    └─registration
           login.html・・・・(7)

(1)accounts

Djangoの認証機能を作成するには、accountsアプリケーションを作成します

cmd.prompt
(venv) C:\data\python\work\myproject>python manage.py startapp accounts

(2)accounts\urls.py

accounts\urls.pyを作成します。

accounts\urls.py
from django.urls import path
from . import views

app_name = 'accounts'
urlpatterns = [
    path('', views.index, name='index'),
]

(3)accounts\views.py

@login_required をつけると、このviewにアクセスするときに認証が必要になります

accounts\views.py
from django.shortcuts import render
from django.contrib.auth.decorators import login_required

@login_required
def index(request):
    return render(request, 'accounts/top.html')

(4)static\css\style.css

画面全体のスタイルを定義します。

static\css\style.css
@charset "UTF-8";

.mysystem-header{
  background: #3333FF !important;
  color: white !important;
}
.mysystem-border{
  background: #3333FF !important;
  color: white !important;
}

(5)accounts\top.html

認証後に表示するtop画面を作成します

accounts\top.html
{% extends "commons/base.html" %}

{% block title %}メニュー{% endblock %}

{% block styles %}
nav.menu ul li {
    list-style-type:none;
    font-size: 1.1em;
}
{% endblock %}

{% block headertitle %}メニュー画面{% endblock %}

{% block content %}
<nav class="menu">
  <ul>
      <li>
        <a target="_blank" href="/hello">Hello World!</a>
      </li>
  </ul>
</nav>
{% endblock %}

{% block scripts %}
<script>
</script>
{% endblock %}

(6)commons\base.html

共通テンプレートです

commons\base.html
{% load staticfiles %}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
    <title>
      {% block title %}{% endblock %}
    </title>
    <style>
        body {
          padding : 10px;
        }
        div.container {
          min-width:600px;
        }
        nav ul#menu {
            margin:0px;
            padding:0px;
        }
        nav ul#menu li {
            float:right;
            list-style-type:none;
            text-decoration: underline;
            padding-left: 10px;
        }
        div.header {
          padding: 10px;
        }
        div.header * {
          color: white !important;
        }
        div.header .title {
          font-size: 1.2em;
        }
        {% block styles %}{% endblock %}
    </style>
</head>
<body>
<div class="container">
  <div class="inner">
    <div class="row header mysystem-header">
      <div class="col-sm title">
        {% block headertitle %}{% endblock %}
      </div>
      <div class="col-sm">
        <nav class="pull-right">
            <ul id="menu">
              {% if user.is_authenticated %}
                <li><a href="{% url 'logout' %}" class="logout">Logout</a></li>
              {% else %}
              {% endif %}
            </ul>
        </nav>
      </div>
    </div>
    <br/>
    <div class="content">
        {% block content %}{% endblock %}
    </div>
  </div>
</div>
<script src="{% static "js/jquery-3.3.1.min.js" %}"></script>
<script src="{% static "js/bootstrap.bundle.min.js" %}"></script>
{% block scripts %}{% endblock %}
</body>
</html>

(7)registration\login.html

ログイン画面です
:point_up_2:templateファイルは、Djangoの「registration」フォルダに入れておく必要があります

registration\login.html
{% load staticfiles %}
{% load bootstrap4 %}
<!DOCTYPE html>
<html lang="ja-JP" >
<head>
    <title>ログイン</title>
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <link rel="stylesheet" type="text/css" href="/static/admin/css/responsive.css" />
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css' %}">
    <link rel="stylesheet" href="{% static 'css/style.css' %}">
    <style>
    .login #container {
        width: 30em !important;
        min-width: 300px;
        margin: 100px auto;
        border-style: solid;
        border-color: #3333FF;
    }
    div.form-group {
      padding-top: 20px;
    }
    div#header {
      padding: 10px;
    }
    div#content-main {
      padding: 20px;
    }
    </style>
</head>

<body class=" login" data-admin-utc-offset="32400">
<div id="container">
  <div class="inner">
    <div id="header" class="mysystem-header">
              ○○管理システム
    </div>
    <div id="content" class="colM">
      <div id="content-main">
        <form method="post" action="{% url 'login' %}">
        {% csrf_token %}
        {% bootstrap_form form layout='horizontal' %}
        <div class="form-group row px-3">
          <input type="submit" class="btn btn-primary btn-block" value="ログイン" />
        </div>
        <input type="hidden" name="next" value="{{ next }}" />
        </form>
      </div>  <!-- content-main -->
      <br class="clear" />
    </div>  <!-- content -->
  </div>  <!-- inner -->
</div>  <!-- END Container -->
</body>
</html>

:point_up_2:bootstrap_form でformを描画しています。
{% bootstrap_form form layout='horizontal' %}

(8)settings.py

settings.pyを編集します

settings.py

INSTALLED_APPS = [ 'accounts.apps.AccountsConfig', #追加 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'bootstrap4', #追加 ] ・・・・ # Authentication LOGIN_URL = '/' #ここで定義したURLに入ると、template/registration/login.htmlに移動 LOGIN_REDIRECT_URL = '/dashboard/' #任意の行に追加 LOGOUT_REDIRECT_URL = '/accounts/login/' #任意の行に追加 LOGOUT_REDIRECT_URL='/' #任意の行に追加

bootstrap4は、pipでインストールできます
ログアウトでは、ルートを表示するようにしておきます。

(9)myproject\urls.py

・accountsにアクセスすると、Djagoの認証用のサイトにアクセスします
・ルートにアクセスすると、「accounts」アプリのサイトにアクセスします

myproject\urls.py
・・・
urlpatterns = [
    path('accounts/', include('django.contrib.auth.urls')), #  追加
    path('', include('accounts.urls')), #"追加"
    path('admin/', admin.site.urls),
]

ルートのURLをaccountsにすることで、topページが表示されるようにしておきます。

動作確認してみます。

cmd.prompt
(venv) C:\data\python\work\myproject>manage.py runserver

http://localhost:8000/にアクセスします

image.png

「2.管理ユーザを作成する」で作成したスーパーユーザでログインしてみます

image.png

ログインできました。Djangoは、認証の実装も簡単ですね。


+ Recent posts