tohokuaikiのチラシの裏

技術的ネタとか。

LaravelのSanctumでBearer Tokenを取得して使用したり期限を設定したり

使っているLaravelは11なので、デフォルトでSanctumがインストールできるのですがそのあたりは公式サイトにて割愛。

laravel.com

やりたいこと

ログイン時にBearer Tokenで使えるTokenを発行して、そのTokenの管理をしたり有効期限を設定したりする。

Tokenの発行

ログイン処理をするところにひっかけておく。要はログインした $user が取れればよい。Auth::login()で行う場合は

<?php
Auth::login($user, true);

とかしてる付近の $user を使う。

Inertiajsを使ったセッションコントローラなら

<?php
    public function store(LoginRequest $request): HttpResponse
    {
        /// 省略
        LoginSuccess::dispatch($request->user());

あたりの $request->user() とか。

ModelにTraitでTokenを発行するメソッドを追加

<?php
    use HasApiTokens;

Tokenの発行はcreateToken()メソッド

<?php
$token = $user->createToken('jwt-token')->plainTextToken

引数は何でもいいんだけど、とりあえずjwt-tokenにしておいた。

Tokenの情報は、personal_access_tokens テーブルに保存される。

こんな感じ。

> select * from personal_access_tokens \G;
*************************** 1. row ***************************
            id: 5
tokenable_type: App\Models\User
  tokenable_id: 93
          name: jwt-token
         token: 7cd13a56f215a93d0f0050c04f32590d79cce58cee668dce9037202a9126f40d
     abilities: ["*"]
  last_used_at: NULL
    expires_at: NULL
    created_at: 2025-08-18 13:53:50
    updated_at: 2025-08-18 13:53:50
1 row in set (0.003 sec)

このDBテーブルに入っているTokenはハッシュ化されたものであり、生トークンではないのでこれだけあっても認証には使えない。認証には先ほどのcreateTokenメソッドで取得した $token 変数が必要。

で、このTokenをどうやってログインしたユーザーに知らせるか

生TokenはDBに保存とかしたくない。メールで通知するとかしてもいいかもしれない。とりあえず面倒だったので自分はログイン後のリダイレクトリンクにHTTPヘッダとして仕込んだ。

<?php
return redirect(config('app.admin_path'), 302, [
       'X-JWT-TOKEN' => $user->createToken('jwt-token')->plainTextToken
]);

で、ユーザーにはChromeのDevToolsとかでヘッダ探してなという不親切設計。

有効期限とartisanコマンドの sanctum:prune-expired

artisanコマンドには、sanctum:prune-expired というのがある。これを使うのがよさそう。

データベースの expires_at という幻惑フィールドと、config/sanctum.php について

この expires_at は、ユーザーが自由に使うフィールドで結局のところLaravelは何の面倒も見ない

sanctum:prune-expired コマンドの実行時には以下のようになる。

  1. config('sanctum.expiration') がnullなら何もしない(つまり、Tokenは無期限有効)
  2. nullでないなら、personal_access_tokens テーブルのcreated_at + config('sanctum.expiration') 分 が現在より小さいものを削除する