DjangoでAlamofireのPOSTを扱うときはcsrf_exemptでcsrf機能を外す
2023.02.18
Alamofire で Django のサーバーにアクセスするとき、GET はすんなりうまくいくが、POST はうまくいかない。
Alamofire 側
Alamofire.request(url, method: .post, parameters: parameters).responseJSON{...}
url には POST したいページ、parameters にはサーバーに送りたい変数を指定する。しかしこのままではうまくいかない。次のエラーが表示される。
Alamofire.AFError.responseSerializationFailed...
エラーには jsonSerializationFailed... とあるから、responseJSON が違うかもしれないとか、あれこれ考えてしまう。
試しに .post を .get にすると成功する。Alamofire に headers を設定したり、encoding を encoding: JSONEncoding.default にしたりしても、問題とまったく関係ない。まして responseJSON を別のものに置き換えても意味がない。
原因は Django の csrf
このエラーは
Django は POST で csrf を必要としている
のに
parameters に csrfmiddlewaretoken が入っていないこと
による。Django を使っている人は「あー!そういうだった!」と思うかもしれない。
解決するには Django の API 専用ページだけ csrf を外す必要がある。例えば Django の views で、api_login という関数でログイン API ページを表示しているとする。このとき
@csrf_exempt
def api_login(request):
と関数の上に @csrf_exempt を書く。これは特定のページだけ csrf 機能を外すということ。この「外す機能」は
from django.views.decorators.csrf import csrf_exempt
をインポートしないといけない。