【attemptメソッドが使えない?】Call to undefined method TokenGuard::attempt() の解決法

はい、今回はなんでかわからんけど、attemptメソッドが使えないんだけど?どーすんの。

って状態になったので解決方法を共有しますね。

現在の自分の状況としては、Laravel8.xにsanctumの認証機能を入れようとしたときにエラーが起きたわけです。

認証して、tokenを発行する流れになるのですが、そこの認証がうまくいかない。。。。

そんな状況です。

ゴール: attemptメソッドをどうしたら使えるのか

今回の記事ではsanctum認証の概要を簡単に知って、attemptメソッドを利用して認証処理ができるまでを目的とします。

「ログインどーすんねん」「テーブルどーすんねん。」等などよりも今回はエラー解決を目的としております。

課題: attempt()が定義されていないエラーがでること。

認証controller

public function store(Request $request)
{
    //attemptメソッドの引数に渡すために変数に入れる。
    $name = $request->name;
    $password = $request->password;

    //指定したguardで認証の処理を行う。
    //認証処理を行うカラムはemailとpasswordで指定。
    if (Auth::guard('admin')->attempt(['name' => $name, 'password' => $password])) {

        //guardで認証処理されたuser情報の取得
        $user = Auth::guard('admin')->user();

        //tokenの再生成
        $user->tokens()->delete();
        $token = $user->createToken("login:user{$user->id}")->plainTextToken;

        //成功のレスポンスを返す
        return response()->json(['token' => $token ], Response::HTTP_OK);
    }
}Code language: PHP (php)

こんな感じでguardを指定して認証をしたいときにエラーが発生しました。

なんでかわからんけど↓のようなエラーがでちゃうんですよね。

"Call to undefined method Illuminate\\Auth\\TokenGuard::attempt()"Code language: JSON / JSON with Comments (json)

これは困ったもんだと。

attemptが定義されていないよーってことでsanctumを利用する以下の流れがうまくいかないんですね。

  1. ログイン処理
  2. token発行

ログイン処理のところでエラーがでているんですね。

では原因を探していきましょう。

原因

原因はattemptメソッドはtokenのguardドライバーを使えないっぽいんですよね。

guard関連の知識が怪しい方はこちら↓図解でわかりやすかったです。
[図解] Laravel の認証周りのややこしいあれこれ。

ということで原因はtokenじゃなくて、sessionのguardドライバーを使わないといけないっぽいですね。

解決方法

sessionのguardドライバーを使うには以下のファイルを修正します。

api/config/auth.php

'guards' => [

    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'token',
        'provider' => 'users',
        'hash' => false,
    ],

    //修正箇所↓
    'admin' => [
        'driver' => 'session', //tokenからsessionに変える。
        'provider' => 'admins',
        'hash' => false,
    ]
],
Code language: PHP (php)

そう、自分でguardを作ってtokenにしていたのが問題だったようですね~

あちゃ。。。

sanctum認証のそもそも

sanctumはtokenをつかうからguardもtokenで良いんだー的な感じで、guardでもtokenを指定していたけど違ったみたいですね…

Laravelの公式より以下のようにまとめられていました。

Laravel Sanctumは、アプリケーションの認証プロセス全体を管理できるWeb/APIハイブリッド認証パッケージです。これが可能なのは、Sanctumベースのアプリケーションがリクエストを受信すると、Sanctumは最初に認証済みセッションを参照するセッションクッキーがリクエストに含まれているかどうかを判断するからです。Sanctumは、すでに説明したLaravelの組み込み認証サービスを呼び出すことでこれを実現します。リクエストがセッションクッキーを介して認証されていない場合、SanctumはリクエストのAPIトークンを検査します。APIトークンが存在する場合、Sanctumはそのトークンを使用してリクエストを認証します。

https://readouble.com/laravel/8.x/ja/authentication.html より

  1. 認証に対してはセッションサービスが使われて、認証処理が行われる。
  2. 認証処理が成功したユーザーに対してapi tokenが発行される。

このプロセスでsanctumは利用されるっぽいですね~

ややこしかった。

以下の記事もわかりやすかったです。

【Laravel8.x】Laravel Sanctumについて色々調べたのでまとめておく

まとめ

しっかり自分がやっていることを理解しながら進めないといけない。

毎回ブログを書くタイミングで思う…

勉強勉強

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA