🐍

Django REST frameworkを初めて使って、つまずいたところのまとめ

2023/07/31に公開

初めに

今回業務でDjango REST framework(DRF)を初めて使用してAPIを作りました。導入するにあたり、自分が詰まったところを重点的にまとめておきたいと思います


CSRF検証エラーから抜け出せない

POSTメソッドで送信する際、CSRFのトークンエラーに遭遇し、一旦csrf_exemptを使用して、実装を進めようとしましたが、変わらずエラーが返ってきてしまいました。

またおかしなことにPostmanで使用する分には通るのに、実際のシステム上では上記のエラーが返るというおかしな状況でした



調べてみると、こちらの方の記事がとても参考になりました。
https://zenn.dev/ktnyt/scraps/8ee5e79e09d7b9?utm_source=pocket_saves


rest_frameworkのas_viewメソッドが原因でした。以下は公式のコードです。


@classmethod
    def as_view(cls, **initkwargs):
	...

        view = super().as_view(**initkwargs)
        view.cls = cls
        view.initkwargs = initkwargs

        # Note: session based authentication is explicitly CSRF validated,
        # all other authentication is CSRF exempt.
        return csrf_exempt(view)
# Note: session based authentication is explicitly CSRF validated,
# all other authentication is CSRF exempt.

和訳

注意: セッションベースの認証は、明示的にCSRFの検証を行う、

その他の認証はCSRFの対象外です.

システムではログイン後にリクエストを送っていたため、Postmanで叩く際にはリクエストが通ったことにも納得がいきました。


対応として素直にset_cookieメソッドを使用してフロント側にトークンを返し、リクエストヘッダーにX-CSRFTokenをトークンにセットしリクエストを送るようにしました。(面倒くさがらず初めからやれば良かった)

api

from django.middleware.csrf import get=token
...

def set_token(request, response):
  token = get_token(request)
  response.set_cookie('csrftoken', token)
	

フロント(Vue.js)

import cookies from 'js-cookie'

function setToken() {
  const token = cookies.get('csrftoken')
  axios.defaults.headers.common['X-CSRFToken'] = token
  


エラーメッセージをカスタマイズしたい

DRFでの検証はとても実装しやすかったのですが、(個人的に)エラーメッセージに違和感があり、カスタマイズしました。やり方を簡単にですが残しておきます。

エラーメッセージをカスタマイズする際には、シリアライザークラスを定義する際に、フィールドにerror_messagesを定義することで、カスタマイズできます。

class UserSerializer(serializers.Serializer):
    id = serializers.IntegerField()
    username = serializers.CharField(
        max_length=30,
        error_messages={
            "blank": "名前を入力してください",
            "max_length": "名前は30文字以内で入力してください"
        }
    )
    email = serializers.EmailField(
        error_messages={
            "blank": "メールアドレスを入力してください",
            "invalid": "有効なメールアドレスを入力してください"
        }
    )

エラーメッセージはkey, valueの辞書形式で返却されます。カスタマイズしたい際は、一度エラーを発生させてkeyを確認し、error_messagesに該当のkey, 表示したいエラーメッセージと辞書形式で代入することでカスタマイズすることが可能です。

Discussion