1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

laravel Sanctum SPA認証 ログアウト系のテストコードでエラーが発生する(users.remember_tokenを使わないようにする)

Last updated at Posted at 2023-06-30

概要

  • 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が返るようになった。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?