参考资料:
Laravel Sanctum目的
快速发行给分离式前端使用的 Token
一、安装 Sanctum
使用指令安装:
composer require laravel/sanctum
建立设置:
php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider"
执行 migrate:
貌似 Laravel 9 在建立专案时已经包含这个 migration ,因此没执行是正常的
php artisan migrate
编辑 App/Http/Kernel.php
将 Middleware 添加至 api 中:
Laravel 9 预设就已经有了,将注解拿掉就好
'api' => [ \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, 'throttle:api', \Illuminate\Routing\Middleware\SubstituteBindings::class,],
如果不是使用预设的 Users 资料表登入的话:
则需要修改 config/sanctum.php
,并在 guard
后面补上你在 config/auth.php
中新增的 guard
:
'guard' => ['web', 'store'],
二、取得 token
先编辑要使用 token 的 Model,加入 HasApiTokens
:
use Laravel\Sanctum\HasApiTokens;class Store extends Authenticatable{ use HasApiTokens, HasFactory;...
之后就能使用 createToken
方法去产生 token:
$user->createToken('token-name')->plainTextToken;
三、範例
使用 AuthController 来实作 API 登入,并取得 token:
use Validator;use Auth;class AuthController extends Controller{ public function storeLogin (Request $request) { $validator = Validator::make($request->all(), [ 'username' => 'required', 'password' => 'required|min:6', ]); if ($validator->fails()) return response()->json(['message' => $validator->errors()->first()], 400); if (Auth::guard('store')->attempt(['username' => $request->username, 'password' => $request->password])) { $store = Auth::guard('store')->user(); return $store->createToken('jwt')->plainTextToken; } return response()->json(['message' => 'username or password incorrect'], 400); }}
四、限制路由
编辑 routes/api.php
,一样将要受 token 保护的路由放入 middleware :
// 登入Route::post('/store-login', 'App\Http\Controllers\AuthController@storeLogin');Route::middleware(['auth:sanctum'])->group(function () { Route::get('/posts', function () { return '200'; });});
注意事项!!
如果 ID 不是整数,则需要修改资料表 personal_access_tokens
将 tokenable_id
改为 String
public function up() { Schema::table('personal_access_tokens', function (Blueprint $table) { $table->string('tokenable_id')->change(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::table('personal_access_tokens', function (Blueprint $table) { $table->unsignedBigInteger('tokenable_id')->change(); }); }