ここまでの作業でコメントの表示だけでなく投稿や更新・削除の API ができました.しかしながら,誰もが全ての投稿にアクセスできて,更新や削除も自由にできてしまうという設計は現実的な状況を考えると問題がありそうです.
したがって,ここからはユーザを登録し,ユーザ認証ができるようにします.この上で,誰もが閲覧でき自分の投稿だけを編集できるケースや,自分の投稿だけを閲覧・編集できるケース,など目的に応じた設計ができるようにします.なお,これから登録するユーザの情報は次の通りです.
ユーザ名 | メールアドレス | パスワード |
---|---|---|
user_a | a@sample.com | password |
user_b | b@sample.com | password |
user_c | c@sample.com | password |
まず,ユーザを登録の前に,データベースのテーブルにデータが投入されていないことを確認しておきます.ユーザ情報は auth_user
テーブルに格納されます.SQlite を起動して,次の通り確認します.
sqlite> .tables ⏎ auth_group comments_comment auth_group_permissions django_admin_log auth_permission django_content_type auth_user django_migrations auth_user_groups django_session auth_user_user_permissions sqlite> select * from auth_user; ⏎ sqlite>
次に,shell を用いて3名のユーザを登録します.
...\django_comment_api>python manage.py shell ⏎ Python 3.10.9 | packaged by Anaconda, Inc. | (main, Mar 1 2023, 18:18:15) [MSC v.1916 64 bit (AMD64)] Type 'copyright', 'credits' or 'license' for more information IPython 8.10.0 -- An enhanced Interactive Python. Type '?' for help. In [1]: from django.contrib.auth.models import User ⏎ In [2]: user = User.objects.create_user('user_a', 'a@sample.com', 'password') ⏎ In [3]: user.save() ⏎ In [4]: user = User.objects.create_user('user_b', 'b@sample.com', 'password') ⏎ In [5]: user.save() ⏎ In [6]: user = User.objects.create_user('user_c', 'c@sample.com', 'password') ⏎ In [7]: user.save() ⏎ In [8]: exit() ⏎ ...\django_comment_api>
正しく登録できているか SQLite で確認します.
sqlite> select * from auth_user; ⏎ id|password|last_login|is_superuser|username|last_name|email|is_staff|is_active|date_joined|first_name 1|pbkdf2_sha256$600000$Pyo5BUOSWvH6vHwbKOD05e$qbXt6gxpXNiVWNevy+pC7NTyif6FnJ/9G5R6BtAbt3k=||0|user_a||a@sample.com|0|1|2023-11-23 16:05:04.397836| 2|pbkdf2_sha256$600000$OuR4219xvoiaQlcmxcD41x$OVlnlgfNyWeaLn00KDXibU85Zbx2YDH5GbZ3UdIpOnA=||0|user_b||b@sample.com|0|1|2023-11-23 16:05:19.321485| 3|pbkdf2_sha256$600000$rMHLWfTGTpaUkz1cUGDUAk$dRG5oQiTL3ecjNMJfWDNNwh0FpYWv+mMvBgs7jZ9TmY=||0|user_c||c@sample.com|0|1|2023-11-23 16:05:30.269097| sqlite>
パスワードは NIST が推奨する PBKDF2 アルゴリズムと SHA256 ハッシュにより保護されています.パスワードは 【<アルゴリズム>$<イテレーション回数>$<ソルト>$<ハッシュ>】 の形式で保存されています.3名のユーザが同じパスワード「password」を設定していますが,ソルトが異なるので結果的には異なるハッシュとして保存されていることに注意してください.Django のパスワード管理についての詳細はこちらを参照してください.
ユーザの登録ができたので,curl
コマンドで接続するときにユーザ情報を追加してみます.(1) ではユーザ名なしで接続できていることがわかります.(2) では -u ユーザ名:パスワード
のオプションを指定して接続しています.正しいユーザ名とパスワードで接続できていることがわかります.(3) ではパスワードが異なるのでエラーが表示されました.
...\django_comment_api>curl http://127.0.0.1:8000/comments/ ⏎ # (1) {"count":11,"next":"http://127.0.0.1:8000/comments/?page=2","previous":null,"results":[{"id":13,"title":"0123456789","body":"012345678901234","updated_at":"2023-11-23T15:24:38.905335"},{"id":9,"title":"9個目のコメント","body":"コメントの本 文9","updated_at":"2023-11-23T11:20:00"}]} ...\django_comment_api>curl -u user_a:password http://127.0.0.1:8000/comments/ ⏎ # (2) {"count":11,"next":"http://127.0.0.1:8000/comments/?page=2","previous":null,"results":[{"id":13,"title":"0123456789","body":"012345678901234","updated_at":"2023-11-23T15:24:38.905335"},{"id":9,"title":"9個目のコメント","body":"コメントの本 文9","updated_at":"2023-11-23T11:20:00"}]} ...\django_comment_api>curl -u user_a:abc http://127.0.0.1:8000/comments/ ⏎ # (3) {"detail":"ユーザ名かパスワードが違います。"} ...\django_comment_api>
上の通りユーザ認証を行っていますが,現時点ではユーザ情報を付与しなければ全ての操作ができる状態にあることに注意してください.
また,ここでは shell を使ってユーザ情報を登録しました.しかしながら,大きなシステムの開発途中では頻繁にデータベースをリセットすることになります.その都度 shell で一人ひとりのユーザ情報を登録することは手間がかかることから,次のページでは fixtures でデータを登録するようにします.