12
23

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 5 years have passed since last update.

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

Posted at

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ファイルは、「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', #追加
]
・・・・
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

image.png

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

image.png

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

12
23
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
12
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?