はじめに
こんばんは。
前回の続きです。
kojirooooocks.hatenablog.com
短いですがアビリティ試してみました。
本題
前回作ったルートを以下のように修正・追加してみました。
<?php
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
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', ['user'])->plainTextToken]);
});
route::post('/login/super', 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();
return response()->json(['access_token' => $user->createToken('auth_token', ['super', 'user'])->plainTextToken]);
});
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();
return response()->json(['access_token' => $user->createToken('auth_token', ['user'])->plainTextToken]);
});
Route::middleware(['auth:sanctum', 'ability:user'])->get('/logout', function (Request $request) {
$request->user()->tokens()->delete();
return "OK";
});
Route::middleware(['auth:sanctum', 'ability:user'])->get('/user/myself', function (Request $request) {
return $request->user();
});
Route::middleware(['auth:sanctum', 'ability:super'])->get('/user/{user}', function (User $user) {
return $user;
});
登録時は user
というアビリティが付与されます。
そしてログインが二通りあって、 /login/super
の場合は user
以外に super
のアビリティが付与されます。
super
が付与されている場合のみ 自分以外の他のユーザーの情報が見れる /user/{user}
にアクセスできます。
データの事前準備
事前に ユーザーデータを2件登録しておきます。
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 |
| 2 | kojikoji | example_kojikoji@xxx.com | NULL | $2y$10$6HfoExYa9.SrNDTIpA0F9uPCRN5oGcZTXG99ORtlWCHu6OhfkWFfi | NULL | 2022-07-16 16:01:58 | 2022-07-16 16:01:58 |
+----+----------+--------------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+
2 rows in set (0.00 sec)
ノーマルユーザーでログイン
mysql> select * from personal_access_tokens;
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
| id | tokenable_type | tokenable_id | name | token | abilities | last_used_at | created_at | updated_at |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
| 1 | App\Models\User | 1 | auth_token | 235e76ef3da41fbc897f87215cf9a79821071738357dd61cfa9d16ab92fb537d | ["user"] | NULL | 2022-07-16 16:34:20 | 2022-07-16 16:34:20 |
+----+-----------------+--------------+------------+------------------------------------------------------------------+-----------+--------------+---------------------+---------------------+
1 row in set (0.01 sec)
abilities
に user
がセットされています!
この状態で、アクセスできるURLにアクセスしてみます。
問題なくアクセスできました。
次に、アクセスできないURLにアクセスしてみます。
403でアクセスが拒否されました。
スーパーユーザーでログイン
mysql> select * from personal_access_tokens;
+----+-----------------+--------------+------------+------------------------------------------------------------------+------------------+--------------+---------------------+---------------------+
| id | tokenable_type | tokenable_id | name | token | abilities | last_used_at | created_at | updated_at |
+----+-----------------+--------------+------------+------------------------------------------------------------------+------------------+--------------+---------------------+---------------------+
| 2 | App\Models\User | 1 | auth_token | 2773ee81be6355be8b228a57b1944b32917f1e32c74d0869eb9fea54b4136c6e | ["super","user"] | NULL | 2022-07-16 16:37:28 | 2022-07-16 16:37:28 |
+----+-----------------+--------------+------------+------------------------------------------------------------------+------------------+--------------+---------------------+---------------------+
1 row in set (0.00 sec)
abilities
に super
と user
がセットされています。
この状態で、先程アクセスできなかったURLにアクセスしてみます。
アクセスできました。
終わりに
こんな感じでとてもかんたんでした。
ちなみに今回試さなかった abilities
ミドルウェアの方は指定したアビリティを すべて持っていること
が条件のようです。
今回の ability
ミドルウェアは 指定したアビリティを どれか一つを持っていること
が条件です。
今回は1個しか使ってなかったのですが、もっと複雑な権限制御がある場合は効果ありそうですよね。
次は何試そうかなぁ。
現場からは以上です。