概要
- laravelにてSanctumでSPA認証を実施してログアウト系のテストコードを実行したところエラーが発生したの解消までの流れを簡単にまとめる。
エラーまでの経緯
-
下記のようなテストコードを記載した。
test.php/** * 正常系 ログアウト成功 * * @return void */ public function test_ログアウト成功(): void { $this->withoutMiddleware(VerifyCsrfToken::class); $user = User::factory()->create(['email' => 'test1@example.com']); // レスポンスチェック $response = $this->actingAs($user) ->postJson('/logout'); $response->assertStatus(200) ->assertJson([ 'message' => 'Unauthenticated.' ]); // ゲスト状態を確認 $this->assertGuest(); }
エラー
-
テストコードを実行したところ500エラーが帰ってきた。
-
下記のように修正してテストを再度走らせて500エラーの内容を確認した。
test.php/** * 正常系 ログアウト成功 * * @return void */ public function test_ログアウト成功(): void { $this->withoutMiddleware(VerifyCsrfToken::class); $user = User::factory()->create(['email' => 'test1@example.com']); // レスポンスチェック $response = $this->actingAs($user) ->postJson('/logout'); dd($response); // $response->assertStatus(200) // ->assertJson([ // 'message' => 'Unauthenticated.' // ]); // // // ゲスト状態を確認 // $this->assertGuest(); }
-
下記のようなエラーが得られた。
The attribute [remember_token] either does not exist or was not retrieved for model [App\Models\User].
-
usersテーブルのremember_tokenカラムは使わないので今回マイグレーションから削除している。
エラー解消までの経緯
-
どうやらremember_tokenカラムを削除するだけだと、laravelは「remember_tokenを使わない設定」にならないらしい。
-
Userモデルクラスの継承元である
Illuminate\Foundation\Auth\User as Authenticatable
を見てみる。Illuminate\Foundation\Auth\User.php<?php namespace Illuminate\Foundation\Auth; use Illuminate\Auth\Authenticatable; use Illuminate\Auth\MustVerifyEmail; use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract; use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract; use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract; use Illuminate\Database\Eloquent\Model; use Illuminate\Foundation\Auth\Access\Authorizable; class User extends Model implements AuthenticatableContract, AuthorizableContract, CanResetPasswordContract { use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail; }
-
Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract
のインターフェースの実装を本クラスですることになっており、当該クラスの実装メソッドはIlluminate\Auth\Authenticatable
のトレイトを呼び出すことで賄っている。 -
Illuminate\Auth\Authenticatable
の関係ありそうなメソッドを見てみる。Illuminate\Auth\Authenticatable.php/** * Get the token value for the "remember me" session. * * @return string|null */ public function getRememberToken() { if (! empty($this->getRememberTokenName())) { return (string) $this->{$this->getRememberTokenName()}; } } /** * Set the token value for the "remember me" session. * * @param string $value * @return void */ public function setRememberToken($value) { if (! empty($this->getRememberTokenName())) { $this->{$this->getRememberTokenName()} = $value; } } /** * Get the column name for the "remember me" token. * * @return string */ public function getRememberTokenName() { return $this->rememberTokenName; }
-
上記のメソッドたちをUserモデルクラスでオーバーライドして使わないようにする。
User.php/** * Get the remember token value. * * @return string|null */ public function getRememberToken(): string|null { return null; } /** * Set the remember token value. * * @param string $value * @return void */ public function setRememberToken($value): void { // Do nothing. } /** * Get the name of the remember token. * * @return string */ public function getRememberTokenName(): string { return ''; }
-
テストを走らせると200が返るようになった。