今回はSanctumを使って行きます。
routingでどのユーザがどんな処理ができるのか等を制限していきます!
controllerにgateを使って書いていく方法もありますが、なかなか管理も難しいですしroutingを一目見ただけで誰が、どんな事をできるのかを知りたいときには不便だと思います。
では、進めていきます。
参考ブログ、資料は以下です。
Table of Contents
まず初めに。
まず初めに簡単な認証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番目の引数として渡すことができます。
これでログインすることで権限が渡されます。
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を使うと簡単にはできるけど、今後オリジナルで改造していくのとかは大変そう。
理解理解、深めていく。