【Django】スーパーユーザーの登録・確認・変更


投稿日 2020年9月5日 >> 更新日 2023年3月1日

今回はDjangoのスーパーユーザー権限の登録・確認・変更を管理画面、もしくわUserモデルを使用したデータベースAPIをインタラクティブシェルにて実装していきたいと思います。

もちろんスーパーユーザーの登録を行い管理画面をログインできれば、ブラウザ上でユーザー情報の確認・変更を簡単に行うことができます。

がしかし、ユーザー名やパスワードを忘れてしまった場合などは、Djangoのインタラクティブシェルを実行し、データベースに保存されているユーザー情報を呼び出したり変更することができます。

今回は初心に戻って、スーパーユーザーの登録から、インタラクティブシェルでの変更まで実装していきたいと思います。

実行環境&使用ライブラリ

実行環境
Windows Subsystem for Linux
Python 3.6.9
pip 9.0.1
使用ライブラリ ライセンス
Django==3.1 BSD

スーパーユーザーの登録

Djangoでは3つのパーミッション(権限)が用意されていて、弱い方から「有効」「スタッフ」「スーパーユーザー」となっています。

「有効」では、開発されたサービスを主に操作する権限が許されており、「スタッフ」では管理画面等で限られた操作の権限が許されています。

その中で全体の管理が許されているのが「スーパーユーザー」となります。

もちろん権限の範囲もカスタムをすることができますが、ここでは行いません。

それではさっそくDjangoプロジェクトのディレクトリ「manage.py」ファイルのある階層でスーパーユーザーを作成します。


$ python3 manage.py createsuperuser
ユーザー名 (leave blank to use 'UserName'): admin
メールアドレス: admin@sample.com
Password:
Password (again):
このパスワードは短すぎます。最低 8 文字以上必要です。
このパスワードは一般的すぎます。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

他にも、「createsuperuser」コマンドのオプションで、ユーザー名とメールアドレスを先に入力することができます。

※初期登録の場合は素直に実行されます。

$ python3 manage.py createsuperuser --username=admin --email=admin@sample.com
Password:
Password (again):
このパスワードは短すぎます。最低 8 文字以上必要です。
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

やっぱり違うパスワードにしたいという場合は「changepassword ユーザー名」コマンドを使用します。

$ python3 manage.py changepassword admin
Changing password for user 'admin'
Password:
Password (again):
このパスワードは短すぎます。最低 8 文字以上必要です。
このパスワードは一般的すぎます。
Password:
Password (again):
Password changed successfully for user 'admin'

スーパーユーザーコマンドでの設定では、8文字以下でもパスワードを設定することができましたが、「changepassword」コマンドでは8文字以上が絶対条件となります。

これで、プロジェクトディレクトリ内の「urls.py」に設定されているURLを開いて、ログインを行えます。

# config/urls.py

from django.contrib import admin
from django.urls import path

urlpatterns = [
    path('admin/', admin.site.urls),  # 127.0.0.1:8000/admin/
]

管理画面でユーザー情報の確認・変更

サーバーを起動してadminインターフェイスにアクセスします。


$ python3 manage.py runserver
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
September 05, 2020 - 09:13:33
Django version 3.1, using settings 'config.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

URL「http://127.0.0.1:8000/admin」にアクセスしてログインをすると管理画面に入ることができ、「ユーザー」のモデル、もしくわテーブルが既に存在しています。

「ユーザー」をクリックしてみると、登録されているユーザーの一覧を確認できます。

スーパーユーザーとして作成したので、もちろん「スタッフ権限」は有効になっており、最初に明記したユーザー名、メールアドレスも登録されています。

「ユーザー名」をクリックすると詳細情報を確認することができ、ファーストネームやラストネームの追加、ユーザー名やメールアドレス、パーミッション(権限)の変更を行う事ができます。

パスワードに関しては、生のデータは保存されておらず、Djangoが別で管理しているとのことです。

パスワードを変更する場合は、ナビゲーションバーの右上にある項目をクリックします。

すると変更フォームへ遷移されますが、既存のパスワードの確認と、8文字以上の新しいパスワードの変更が求められます。

非常に便利なadminインターフェイスでしたが、パスワードを忘れてしまいログインができなくなってしまった場合などは、インタラクティブシェルでUserモデルを操作できればさらに便利です。

インタラクティブシェルで管理者の確認・変更

先ほど「changepassword」コマンドによりコンソール上でパスワードの変更を行えましたが、Djangoのシェルを起動して、データベースAPIによる確認や変更、そしてユーザーの追加なども行うことができます。

ではコンソール上で「shell」コマンドを実行します。


$ python3 manage.py shell

DjangoではデフォルトでUserモデルが定義されており、登録されたユーザーは全てUserモデルへ保存されます。

>>>
>>> from django.contrib.auth.models import User
>>>
>>> User.objects.all()
<QuerySet [<User: admin>]>
>>>

現在は自分自身だけの情報が保存されいますが、他に様々な権限を持ったユーザーが保存されていると、絞り込んで取得することができます。

>>>
>>> # Trueはスーパーユーザー
>>> User.objects.filter(is_superuser=True)
<QuerySet [<User: admin>]>
>>>
>>> # Falseはスタッフ、一般ユーザー
>>> User.objects.filter(is_superuser=False)
<QuerySet []>
>>>

パーミッションの種類は3つで、それぞれTrue or Falseによって付与されているか確認することが出来ます。

属性 内容
is_active 有効(一般ユーザー)
is_staff スタッフ
is_superuser スーパーユーザー

ユーザー名・パスワード等の追加・変更

では先ほどのシェルの続きですが、インスタンスを生成してそれぞれの属性値を使って中身を確認してみます。

>>> user = User.objects.get(username='admin')
>>> user
<User: admin>
>>>
>>> # 新しく関数を定義してそれぞれの属性値を取得できるようにする
>>> def admin_params(x):
...     print(x.username)
...     print(x.email)
...     print(x.password)
...     print(x.first_name)
...     print(x.last_name)
...     print(x.is_active)
...     print(x.is_staff)
...     print(x.is_superuser)
...
>>>
>>> admin_params(user)
admin
admin@sample.com
pbkdf2_sha256$216000$EeIhOC4jcM8a$KR2+ffjfOmMcxzo6g7LyByiv8xqt1+hzQTnbgbu21CU=


True
True
True
>>>
属性 内容
username ユーザー名
emai メールアドレス
password パスワード
first_name
last_name
is_active 有効(一般ユーザー)
is_staff スタッフ
is_superuser スーパーユーザー

パスワードのデータは他の文字列によって置き換えられています。

「ファーストネーム」と「ラストネーム」が空のままなので、それぞれの属性値に要素を追加してみます。

>>>
>>> user.first_name = 'ゲンドウ'
>>> user.last_name = '六分儀'
>>> user.save()
>>>
>>> admin_params(user)
admin
admin@sample.com
pbkdf2_sha256$216000$EeIhOC4jcM8a$KR2+ffjfOmMcxzo6g7LyByiv8xqt1+hzQTnbgbu21CU=
ゲンドウ
六分儀
True
True
True
>>>

この調子で、それぞれの属性値に要素を与えると、追加もしくわ変更を行うことができますが、セキュリティの関係上「パスワード」だけは特別で他のメソッドを使用する必要があります。

試しに「password」属性を使って要素を変更してみます。

>>> user.username = 'django'
>>>
>>> user.password = 'admin'
>>> user.save()
>>>
>>> admin_params(user)
django
admin@sample.com
admin  # パスワードになっていない
ゲンドウ
六分儀
True
True
True
>>>

ユーザー名は新しい要素に変更されていますが、パスワードでは「admin」という明示的な生のデータが追加されてしまっています。

別途ターミナルを準備してadminインターフェイスにアクセスを試みても、ログインできない状態となってしまいます。

パスワード変更用のメソッドは「set_password()」によって書き換えられます。

メソッド 内容
check_password('password') True or Falseで生のデータが正しいか確認
set_password('password') 生のデータをパスワードとして保管
>>> user.check_password('admin')
False
>>>
>>> user.set_password('admin')
>>> user.save()
>>>
>>> user.check_password('admin')
True
>>>
>>> admin_params(user)
django
admin@sample.com
pbkdf2_sha256$216000$JeXZMmV3fVYt$lxCoB80RdxUdRlEjD8kNg79auSndoYIRmnJKrPG1SVE=
ゲンドウ
六分儀
True
True
True
>>>
>>> quit()

変更後は必ず「save()」メソッドを呼び出して確実に保存しましょう。

管理画面を確認してみると

しっかり追加・変更されていることが分かります。

他にも様々なメソッドがあるので、余力のある方は試してみましょう

それでは以上となります。

最後までご覧いただきありがとうございます。

参考