Django REST frameworkを初めて使って、つまずいたところのまとめ
初めに
今回業務でDjango REST framework(DRF)を初めて使用してAPIを作りました。導入するにあたり、自分が詰まったところを重点的にまとめておきたいと思います
CSRF検証エラーから抜け出せない
POSTメソッドで送信する際、CSRFのトークンエラーに遭遇し、一旦csrf_exempt
を使用して、実装を進めようとしましたが、変わらずエラーが返ってきてしまいました。
またおかしなことにPostmanで使用する分には通るのに、実際のシステム上では上記のエラーが返るというおかしな状況でした
調べてみると、こちらの方の記事がとても参考になりました。
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