2021/02/16
Django ログイン DjangoRESTFramework テストDjangoやDRFのテストクライアントにヘッダーを設定する方法
DRFでSimple-JWTを使ってJWT認証できるようにした。
Simple-JWTを使うと、ヘッダーに Authorization: JWT <アクセストークン>
を設定することでユーザー認証できるようになる。
テストを書く時に、このヘッダーの設定方法がわからなかったので調べた。
バージョン
- Django 3.1.5
- djangorestframework 3.12.2
- pytest 6.2.2
うまくいかない例
はじめは、headersに設定してみたがうまくいかなかった。
headersでAuthorization設定
class TestClass:
def test_hoge(self, client):
res = client.get("/api/target/path/", headers={"Authorization": f"JWT {トークン}"})
うまくいった例
kwargs(可変長キーワード引数)にHTTP_ヘッダー名
の形で指定したらうまくいった。
動いた
class TestClass:
def test_hoge(self, client):
res = client.get("/api/target/path/", HTTP_AUTHORIZATION=f"JWT {トークン}")
今回はpytestのclientフィクスチャを使ったけど、Django標準のテストクライアントでも同じ話のはず。
公式ドキュメントでは以下の箇所で言及されている。
- https://docs.djangoproject.com/en/3.1/topics/testing/tools/#django.test.Client
- https://docs.djangoproject.com/en/3.1/topics/testing/tools/#django.test.Client.get
DRFのAPIClientでヘッダー設定
DRFのAPIClientではcredentialsを使うことで同様のことができる模様。(動作未確認)
APIClientにヘッダー設定
client = APIClient()
client.credentials(HTTP_AUTHORIZATION=f"JWT {トークン")
テストコードでJWTトークンの取得
テストコードでJWTトークンを取得する方法もついでに書いておく。テストデータの生成にはfactoryboyを使っている。
Userファクトリー
class UserFactory(factory.django.DjangoModelFactory):
password = factory.PostGenerationMethodCall("set_password", "testpass")
class Meta:
model = User
テストファイル
user = UserFactory()
res = client.post("/api/token/", data={"username": user.username, "password": "testpass"}, content_type="application/json")
token = res.json()["access"]
トークンを使わずログイン
そもそもトークンを使う必要はなくただログイン状態にできれば良い場合は、client.login
やclient.force_login
を使った方が楽。
login、force_loginでログインさせる
client.login(username=user.username, password="testpass")
client.force_login(user=user)