【Laravel8.x】Sanctumを使ってroutingで権限管理してみた。単一テーブルマルチログイン?

今回はSanctumを使って行きます。

routingでどのユーザがどんな処理ができるのか等を制限していきます!

controllerにgateを使って書いていく方法もありますが、なかなか管理も難しいですしroutingを一目見ただけで誰が、どんな事をできるのかを知りたいときには不便だと思います。

では、進めていきます。

参考ブログ、資料は以下です。

https://blog.capilano-fw.com/?p=6121

https://readouble.com/laravel/8.x/ja/sanctum.html?header=%25E3%2583%2588%25E3%2583%25BC%25E3%2582%25AF%25E3%2583%25B3%25E3%2582%25A2%25E3%2583%2593%25E3%2583%25AA%25E3%2583%2586%25E3%2582%25A3%25E3%2583%259F%25E3%2583%2589%25E3%2583%25AB%25E3%2582%25A6%25E3%2582%25A7%25E3%2582%25A2

まず初めに。

まず初めに簡単な認証APIを作っていきます。

https://yama-weblog.com/using-sanctum-create-auth-api-in-laravel8/

上記の作業が完了した前提で進めます。(※Sanctumを入れて、認証APIができるまでを想定)

権限管理をしたいのでユーザテーブルには”is_admin”カラムを追加しますね。

<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; class CreateUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->boolean('is_admin')->default(false)->comment('trueだとadmin権限を持つ'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
Code language: HTML, XML (xml)

ほい、では進めていきましょう!

LoginControllerの修正

<?php namespace App\Http\Controllers; use Illuminate\Http\Request; //以下より追加 //----------------------------------- use Illuminate\Support\Facades\Auth; use App\Http\Controllers\Controller; use Illuminate\Validation\ValidationException; use App\Models\User; use \Symfony\Component\HttpFoundation\Response; class LoginController extends Controller { public function login(Request $request) { //バリデーション $credentials = $request->validate([ 'email' => 'required|email', 'password' => 'required' ]); //login処理 if (Auth::attempt($credentials)) { $user = User::whereEmail($request->email)->first(); //トークンの作成と取得 //tokenを取得するユーザの権限を設定する。 if ($user->is_admin == true) { $abilities = ['*']; }else{ $abilities = ['user']; } $user->tokens()->delete(); $token = $user->createToken("login:user{$user->id}", $abilities)->plainTextToken; //第二引数にabilities(userの権限を渡す。) //ログインが成功するとtokenを返す。 return response()->json(['token' => $token], Response::HTTP_OK); } return response()->json('Can Not Login.', Response::HTTP_INTERNAL_SERVER_ERROR); } }
Code language: HTML, XML (xml)

今回はユーザの権限を以下のようにします。

  • フルアクセス= *
  • ユーザーアクセス= user
$user = User::whereEmail($request->email)->first(); //トークンの作成と取得 //tokenを取得するユーザの権限を設定する。 if ($user->is_admin == true) { $abilities = ['*']; }else{ $abilities = ['user']; }
Code language: PHP (php)

ここでusersテーブルのis_adminカラムを見てtureだったらフルアクセス権限、falseだったらuser権限を$abilities変数に入れます。

$token = $user->createToken("login:user{$user->id}", $abilities)->plainTextToken;
Code language: PHP (php)

createToken()メソッドの第二引数に権限を入れることで、personal_access_tokensテーブルのabilitiesカラムに引数で渡したものが入れられます。

Sanctumでは、トークンに「アビリティ」を割り当てることができます。アビリティはOAuthの「スコープ」と同様の目的を果たします。能力の文字列配列をcreateTokenメソッドの2番目の引数として渡すことができます。

 参考→  https://readouble.com/laravel/8.x/ja/sanctum.html?header=%25E3%2583%2588%25E3%2583%25BC%25E3%2582%25AF%25E3%2583%25B3%25E3%2581%25AE%25E3%2582%25A2%25E3%2583%2593%25E3%2583%25AA%25E3%2583%2586%25E3%2582%25A3

これでログインすることで権限が渡されます。

routingで管理

先ほど作成した権限をroutingで管理します。

Route::post('/login', [LoginController::class, 'login']);// ログイン //admin権限のあるユーザ Route::middleware('auth:sanctum', 'abilities:*')->group(function(){ Route::get('/admin', function(){ return 'you are admin user'; }); }); //user権限のあるユーザ Route::middleware('auth:sanctum', 'abilities:user')->group(function(){ Route::get('/user', function(){ return 'you are member user'; }); });
Code language: PHP (php)

ほい、こんな感じで、middlewareに’abilities:○○○○’を追加します。

//sanctumによって認証されている。 'auth:sanctum' //personal_access_tokensテーブルのabilitiesカラムを見ている。 'abilities:user'
Code language: JavaScript (javascript)

ただ、これだけではabilitiesは使えないので、アプリケーションの app/Http/Kernel.php ファイルの $routeMiddleware プロパティに以下のミドルウェアを追加します。

app/Http/Kernel.php

'abilities' => \Laravel\Sanctum\Http\Middleware\CheckAbilities::class, 'ability' => \Laravel\Sanctum\Http\Middleware\CheckForAnyAbility::class,
Code language: PHP (php)

これで使えるようになりました!

おおー、こんな感じで簡単に割り振れることができるのね。

sanctum優秀ですな。

sanctumの複数指定

ちなみに、sanctumのアビリティを複数指定するときは以下

—両方を持っている時 (and条件)—

// トークンは"check-status"と"place-orders"アビリティの"両方"を持っている Route::get('/orders', function () { })->middleware(['auth:sanctum', 'abilities:check-status,place-orders']);
Code language: PHP (php)

—どちらかを持っている時 (or条件)—

Route::get('/orders', function () { // Token has the "check-status" or "place-orders" ability... })->middleware(['auth:sanctum', 'ability:check-status,place-orders']);
Code language: PHP (php)

and条件=abillities
or条件=ability

ということになっているようですね。

公式サイト←を引用しました

まとめ

sanctumを使うと簡単にはできるけど、今後オリジナルで改造していくのとかは大変そう。

理解理解、深めていく。

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA