Laravel/JWTを捏造してテストする
JWT: JSON Web Token
JWTAuthライブラリ
JWT: JSON Web Tokenを捏造してテストする
- APIの機能テストにおいて、
「所持しているJWTトークンが認証が通るならtrueを返す」
といったテストを書きたい場合 - 「ログイン済だったらtrueを返す」ではない
- ので、
withoutMiddleware
トレイトでjwt:auth
トレイトをバイパスして\Auth::login($user)
するわけにはいかない
テスト
<?php class FeatureTest extends TestCase { /* ... */ /** * JWT認証をモックするためにリクエストヘッダを捏造する * @see {@link https://stackoverflow.com/questions/30060360/how-to-mock-tymondesigns-jwt-auth-in-laravel-5} */ protected function headers() { $headers = []; $token = JWTAuth::fromUser($this->userDao->find(1)); JWTAuth::setToken($token); $headers['Authorization'] = 'Bearer '.$token; return $headers; } /** * @test */ public function api_auth_check_JWTありでPOSTするとauthenticated_is_trueが返る() { // ---------------------------------------- // 1. 下準備 // JWTトークンヘッダーを捏造する // ---------------------------------------- $headers = $this->headers(); // ---------------------------------------- // 2. アクション // ---------------------------------------- $response = $this->postJson( 'api/auth/check', [], $headers ); // ---------------------------------------- // 3. 検証 // ---------------------------------------- $response->assertStatus(Response::HTTP_OK); $response->assertExactJson(['authenticated' => true]); }
アプリケーション
<?php /** * 所持しているJWTトークンが認証が通るかの確認 * @param Request $request * @return JsonResponse */ public function check(Request $request): JsonResponse { try { JWTAuth::setRequest($request); // テストがモックしたHTTPリクエストを明示的にセットする必要がある JWTAuth::parseToken()->authenticate(); } catch (JWTException $e) { return response()->json(['authenticated' => false]); } return response()->json(['authenticated' => true]); }
JWTAuth::setRequest($request)
は必須- さもないと、(たぶん)
app()->make(Request::class)
したものが注入されており、
Authorization
ヘッダーが設定されていないのでテストが通らない