Python Django 入門トップページ


Django REST Framework による API 開発

  1. API とプロジェクトの概要
  2. Django REST Frameworkのインストール
  3. プロジェクトの作成
  4. 基本設定
  5. アプリケーションの作成と登録
  6. モデルの作成とマイグレーション
  7. テストデータの設定
  8. コメント一覧を出力する API
  9. コメント詳細情報を出力する API
  10. 新規投稿と更新・削除の API
  11. ページネーション
  12. 入力内容の検証(バリデーション)
  13. テストの自動化
  14. Shell でのユーザ登録
  15. Fixtures でのユーザ登録
  16. ユーザ認証を必須にする
  17. コメントにオーナ情報を追加
  18. 権限の設定:Case #1
  19. 権限の設定:Case #2
  20. Python から API への接続
  21. React アプリケーションからの API 接続と CORS エラーの回避

Django REST Framework による API 開発

Shell でのユーザ登録

ここまでの作業でコメントの表示だけでなく投稿や更新・削除の API ができました.しかしながら,誰もが全ての投稿にアクセスできて,更新や削除も自由にできてしまうという設計は現実的な状況を考えると問題がありそうです.

したがって,ここからはユーザを登録し,ユーザ認証ができるようにします.この上で,誰もが閲覧でき自分の投稿だけを編集できるケースや,自分の投稿だけを閲覧・編集できるケース,など目的に応じた設計ができるようにします.なお,これから登録するユーザの情報は次の通りです.

ユーザ名メールアドレスパスワード
user_aa@sample.compassword
user_bb@sample.compassword
user_cc@sample.compassword

まず,ユーザを登録の前に,データベースのテーブルにデータが投入されていないことを確認しておきます.ユーザ情報は 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 でデータを登録するようにします.

目次に戻る