delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

Django REST frameworkでPOSTかつユーザー認証ありのAPIにcurlでリクエストする

概要

Django REST frameworkでAPIを開発している際に、POSTのAPIなのでコマンドラインからcurlデバッグしようとしたところ、掲題の件でハマったのでメモ。

以下の認証を突破する必要がある。

  • ユーザー認証
  • CSRF認証

前提

django-debug-toolbarがインストール済みであること。

手順

1.CSRFトークンとセッションIDの値を確認する。

・任意の画面にブラウザでアクセスして、django-debug-toolbarを開く。

Cookiesessionidcsrftokenの値を確認する。
f:id:kamatimaru:20200616115338p:plain

sessionidcsrftokenの値はリクエスト単位で変化するものではないので、一回控えておけばよい。

2.curlでリクエストする。

・以下のようにcurlでリクエストする。

$ curl -X POST -b "sessionid=5p83l969kh2it7mkq67idg9a2rxlrvo9; csrftoken=0ICxnT6mBJjJojbwGswu54KE2Z1krheGfOhtwFb7T1ev1KMjK3IXhDL7j6GCTLrZ" -H "X-CSRFToken:0ICxnT6mBJjJojbwGswu54KE2Z1krheGfOhtwFb7T1ev1KMjK3IXhDL7j6GCTLrZ" -d "data=dummy" "http://localhost:8000/api/example"

ポイント

CSRFトークンの値をCookiecsrftokenとリクエストヘッダーのX-CSRFTokenの両方に指定する必要があるようである。
※ あくまで検証結果で、内部のロジックを確認した訳ではない。

どちらかしか指定しない場合、認証に失敗する。

Cookieのみ指定した場合

$ curl -X POST -b "sessionid=5p83l969kh2it7mkq67idg9a2rxlrvo9; csrftoken=0ICxnT6mBJjJojbwGswu54KE2Z1krheGfOhtwFb7T1ev1KMjK3IXhDL7j6GCTLrZ" -d "data=dummy" "http://localhost:8000/api/example"
{"detail":"CSRF Failed: CSRF token missing or incorrect."}
$

・X-CSRFTokenのみ指定した場合

$ curl -X POST -b "sessionid=5p83l969kh2it7mkq67idg9a2rxlrvo9" -H "X-CSRFToken:0ICxnT6mBJjJojbwGswu54KE2Z1krheGfOhtwFb7T1ev1KMjK3IXhDL7j6GCTLrZ" -d "data=dummy" "http://localhost:8000/api/example"
{"detail":"CSRF Failed: CSRF cookie not set."}
$