もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

Laravel Sanctumを素振り

はじめに

こんばんは。

今回はLaravel Sanctumを試してみました。

基本的に公式のサイトの通りに進めてみます。

github.com

readouble.com

本番

事前準備

$ composer create-project --prefer-dist laravel/laravel laravel-sanctum-example
$ cd laravel-sanctum-example

$ php artisan --version
Laravel Framework 8.83.18

$ php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
Copied Directory [/vendor/laravel/sanctum/database/migrations] To [/database/migrations]
Publishing complete.

$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table (17.63ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table (13.11ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated:  2019_08_19_000000_create_failed_jobs_table (11.44ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated:  2019_12_14_000001_create_personal_access_tokens_table (18.90ms)

app/Http/Kernel.php

        'api' => [
            \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, ← コメントアウトを外す
            'throttle:api',
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
        ],

routes/api.php

// 追加
use App\Models\User;
use Illuminate\Support\Facades\Hash;

// register
Route::post('/register', function (Request $request) {
    $validatedData = $request->validate([
        'name'     => 'required|string|max:255',
        'email'    => 'required|email|max:255|unique:users',
        'password' => 'required|string|min:16',
    ])
    $validatedData['password'] = Hash::make($validatedData['password']);
    $user = User::create(...$validatedData);

    return response()->json(['access_token' => $user->createToken('auth_token')->plainTextToken]);
});


// login
Route::post('/login', function (Request $request) {
    $credentials = $request->only('email', 'password');
    if (!Auth::attempt($credentials)) {
        return response()->json(['message' => 'login error...'], 401);
    }

    $user = User::where('email', $request['email'])->firstOrFail();
    $token = $user->createToken('auth_token')->plainTextToken;

    return response()->json(['access_token' => $user->createToken('auth_token')->plainTextToken]);
});

// logout
Route::middleware('auth:sanctum')->get('/logout', function (Request $request) {
  $request->user()->tokens()->delete();

  return "OK";
});

HasApiTokens トレイトは試したバージョンではすでに useされています。

register

APIで ユーザーをつくってみます。

DBにもデータが入りました。

mysql> select * from users;
+----+----------+-----------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
| id | name     | email           | email_verified_at | password                                                     | remember_token | created_at          | updated_at          |
+----+----------+-----------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
|  1 | kojirock | example@xxx.com | NULL              | $2y$10$b620QxzvBSd5Vs.lmQQEMulfwq5joOv5zvT1FCoC.pc44LYaLaRYq | NULL           | 2022-07-10 07:55:27 | 2022-07-10 07:55:27 |
+----+----------+-----------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
1 row in set (0.01 sec)

mysql> select * from personal_access_tokens;
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
| id | tokenable_type  | tokenable_id | name       | token                                                            | abilities | last_used_at | created_at          | updated_at          |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
|  10 | App\Models\User |            1 | auth_token | 2bea84929f6a12012dd9492ba8a73a1cf450f52946487b4e0f0c3767a9cd1165 | ["*"]     | NULL                | 2022-07-10 08:14:12 | 2022-07-10 08:14:12 |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
1 row in set (0.00 sec)

login

次にログインしてみます。

トークン情報もはいりました。

 select * from personal_access_tokens;
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
| id | tokenable_type  | tokenable_id | name       | token                                                            | abilities | last_used_at | created_at          | updated_at          |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
| 10 | App\Models\User |            1 | auth_token | 2bea84929f6a12012dd9492ba8a73a1cf450f52946487b4e0f0c3767a9cd1165 | ["*"]     | NULL         | 2022-07-10 08:14:12 | 2022-07-10 08:14:12 |
| 11 | App\Models\User |            1 | auth_token | d29b1ae55dbc78901a423298a20f1272992beee8f7fe5573d758086f0c290177 | ["*"]     | NULL         | 2022-07-10 08:14:12 | 2022-07-10 08:14:12 |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
2 rows in set (0.00 sec)

get user

取得したトークンをセットして ユーザー情報を取得してみます。

last_used_at にデータが入りました。

> select * from personal_access_tokens;
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+---------------------+---------------------+---------------------+
| id | tokenable_type  | tokenable_id | name       | token                                                            | abilities | last_used_at        | created_at          | updated_at          |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+---------------------+---------------------+---------------------+
| 10 | App\Models\User |            1 | auth_token | 2bea84929f6a12012dd9492ba8a73a1cf450f52946487b4e0f0c3767a9cd1165 | ["*"]     | NULL                | 2022-07-10 08:14:12 | 2022-07-10 08:14:12 |
| 11 | App\Models\User |            1 | auth_token | d29b1ae55dbc78901a423298a20f1272992beee8f7fe5573d758086f0c290177 | ["*"]     | 2022-07-10 08:14:55 | 2022-07-10 08:14:12 | 2022-07-10 08:14:55 |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+---------------------+---------------------+---------------------+
2 rows in set (0.00 sec)

ログアウトしてみます。

トークン情報は全て消えました。

mysql> select * from personal_access_tokens;
Empty set (0.00 sec)

終わりに

laravel Passportを昔使ったことありますが、結構めんどくさかった記憶(忘れた...)があったので、これくらいかんたんな方がいいですね。

アビリティ使ったことがないので、つぎはアビリティ使ってどんな事できるか試してみます。

現場からは以上です