djangoでログイン機能を実装してみる

2022年5月3日

djangoでログイン機能を実装してみる

djangoではログインログアウト機能が作れるクラスがすでに用意してあります。
イメージは下の通りです。

それでは下の手順で実装してみましょう。

URLの指定

urls.pyは下の通りです。
importするのを忘れないようにしましょう。
ログインとログアウトのURLを付け加えてあげるシンプルな構成になっています。


#--ログインログアウト----------------------------------
from django.contrib.auth import views as auth_views
app_name = 'app'
urlpatterns = [
        #template_name='app/login.html'でログインページを指定
        path('login/', auth_views.LoginView.as_view(template_name='app/login.html'), name='login'),
        path('logout/', auth_views.LogoutView.as_view(), name='logout'),
]

ログインログアウトの設定

settings.pyに下のコードを追記してください。


#--ログインログアウト---------------------------------------
#未ログインの状態でログインが必要なページへアクセスした時の遷移先
LOGIN_URL           = 'app:login'
#ログイン後の遷移先のページを指定
LOGIN_REDIRECT_URL  = 'app:index'
#ログアウト後の遷移先のページ指定
LOGOUT_REDIRECT_URL = 'app:login'

この状態で下のURLにアクセスするとログアウトが出来ます。
つまりログアウトさせたい時は、ボタン押下時に下のURLに飛ばしてあげるだけで大丈夫です。


http://127.0.0.1:81/app/logout/

あとはログインのページを作っていきましょう。

ログインページの作成

「login.html」は下の通りに作成しました。


{% extends 'app/base.html' %}
{% block content %}
{% load widget_tweaks %}
<div class="message_container">
    {% if form.errors %}
    <div class="login_form_error">ユーザー名かパスワードが間違っています</div>
    {% endif %}
</div>
<table class="login_container">
    <form method="post">{% csrf_token %}
        <tr>
            <td>username</td>
            <td>{{ form.username | add_class:"login_form" }}</td>
        </tr>
        <tr>
            <td>password</td>
            <td>{{ form.password | add_class:"login_form" }}</td>
        </tr>
        <tr>
            <td colspan="2"><button class="positive_button" type="submit">login</button></td>
            <td></td>
        </tr>
    <form>
</table>
{% endblock %}

「{% if form.errors %}{% endif %}」は認証で失敗した時に表示されます。

ここでいきなり「form」が使用できるのは「LoginView」が入力フォームを渡してくれているからです。イメージは下の通りです。

今回は「username」「password」の属性を使用していますが他の属性を確認したい方は、「auth_user」テーブルを確認してみてください。


MariaDB [app]> show columns from auth_user;
+--------------+--------------+------+-----+---------+----------------+
| Field        | Type         | Null | Key | Default | Extra          |
+--------------+--------------+------+-----+---------+----------------+
| id           | int(11)      | NO   | PRI | NULL    | auto_increment |
| password     | varchar(128) | NO   |     | NULL    |                |
| last_login   | datetime(6)  | YES  |     | NULL    |                |
| is_superuser | tinyint(1)   | NO   |     | NULL    |                |
| username     | varchar(150) | NO   | UNI | NULL    |                |
| first_name   | varchar(30)  | NO   |     | NULL    |                |
| last_name    | varchar(150) | NO   |     | NULL    |                |
| email        | varchar(254) | NO   |     | NULL    |                |
| is_staff     | tinyint(1)   | NO   |     | NULL    |                |
| is_active    | tinyint(1)   | NO   |     | NULL    |                |
| date_joined  | datetime(6)  | NO   |     | NULL    |                |
+--------------+--------------+------+-----+---------+----------------+

ログインとログアウトボタンの設置

ヘッダーにログインボタンを設置してみました。


{% load static %}
<!DOCTYPE html>
<html>
<head>
    <title>Django Practice</title>
    <script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
    <script src="{% static 'js/app.js' %}"></script>
    <link rel="stylesheet" type="text/css" href="{% static 'css/style.css' %}">
</head>
<body>
    <header>
        <div class="header_container">
            <h1><a href="{% url 'app:index' %}" class='header'>Django Practice</a></h1>
            <div class="header_menue">
            {% if request.user.is_authenticated %}
                <form method="get" action="{% url 'app:logout' %}">
                    <button type="submit" class="negative_button">logout</button>
                </form>
            {% else %}
                <form method="get" action="{% url 'app:login' %}">
                    <button type="submit" class="positive_button">login</button>
                </form>
            {% endif %}
            </div>
        </div>
    </header>
    <div class="container">
        {% block content %}{% endblock %}
    </div>
</body>
</html>

「{% if request.user.is_authenticated %}{% else %}」で囲んだ部分はログイン中に表示される部分になります。

ユーザーの制御

ログインユーザーを作成したらアクセスの制御をしましょう。
「views.py」に下の通りに記載してあげることで特定のページのアクセスに「ログイン」が必要となります。


from django.contrib.auth.decorators import login_required
@login_required
def xxx(request):
    ...

2022年5月3日