feat: 添加 Laravel Sanctum 支持,增强管理员 API 鉴权,更新相关中间件与路由配置
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('personal_access_tokens', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->morphs('tokenable');
|
||||
$table->text('name');
|
||||
$table->string('token', 64)->unique();
|
||||
$table->text('abilities')->nullable();
|
||||
$table->timestamp('last_used_at')->nullable();
|
||||
$table->timestamp('expires_at')->nullable()->index();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('personal_access_tokens');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('username', 64)->nullable()->after('id');
|
||||
});
|
||||
|
||||
$this->backfillUsernames();
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('username', 64)->nullable(false)->change();
|
||||
$table->unique('username');
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->dropUnique(['email']);
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('email')->nullable()->change();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->dropUnique(['username']);
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->dropColumn('username');
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->string('email')->nullable(false)->change();
|
||||
});
|
||||
|
||||
Schema::table('admin_users', function (Blueprint $table) {
|
||||
$table->unique('email');
|
||||
});
|
||||
}
|
||||
|
||||
private function backfillUsernames(): void
|
||||
{
|
||||
$reserved = [];
|
||||
|
||||
foreach (DB::table('admin_users')->orderBy('id')->cursor() as $row) {
|
||||
$email = (string) $row->email;
|
||||
$local = Str::lower(Str::before($email, '@'));
|
||||
$slug = preg_replace('/[^a-z0-9._-]/', '', $local);
|
||||
$base = Str::substr($slug !== '' ? $slug : 'admin'.(string) $row->id, 0, 50);
|
||||
if ($base === '') {
|
||||
$base = 'admin'.(string) $row->id;
|
||||
}
|
||||
|
||||
$candidate = $base;
|
||||
$n = 0;
|
||||
while (in_array($candidate, $reserved, true)
|
||||
|| DB::table('admin_users')->where('username', $candidate)->where('id', '!=', $row->id)->exists()) {
|
||||
$n++;
|
||||
$suffix = '_'.$n;
|
||||
$candidate = Str::substr($base, 0, 64 - strlen($suffix)).$suffix;
|
||||
}
|
||||
|
||||
$reserved[] = $candidate;
|
||||
|
||||
DB::table('admin_users')->where('id', $row->id)->update(['username' => $candidate]);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -7,7 +7,7 @@ use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
/**
|
||||
* 后台角色(super_admin)、若干权限占位;本地演示:**admin@admin.com** / **123456**(仅限非 production)。
|
||||
* 后台角色(super_admin)、若干权限占位;本地演示:账号 **admin** / **123456**(仅限非 production)。
|
||||
*/
|
||||
class AdminRbacAndUserSeeder extends Seeder
|
||||
{
|
||||
@@ -50,11 +50,12 @@ class AdminRbacAndUserSeeder extends Seeder
|
||||
);
|
||||
}
|
||||
|
||||
$email = 'admin@admin.com';
|
||||
$username = 'admin';
|
||||
AdminUser::query()->updateOrCreate(
|
||||
['email' => $email],
|
||||
['username' => $username],
|
||||
[
|
||||
'name' => 'admin',
|
||||
'name' => '超级管理员',
|
||||
'email' => null,
|
||||
/** 明文;模型 casts `password => hashed`,勿在生产库使用种子弱口令 */
|
||||
'password' => '123456',
|
||||
'status' => 0,
|
||||
@@ -62,7 +63,7 @@ class AdminRbacAndUserSeeder extends Seeder
|
||||
);
|
||||
|
||||
/** @var int $uid */
|
||||
$uid = (int) AdminUser::query()->where('email', $email)->value('id');
|
||||
$uid = (int) AdminUser::query()->where('username', $username)->value('id');
|
||||
DB::table('admin_user_roles')->updateOrInsert(
|
||||
['admin_user_id' => $uid, 'role_id' => $rid],
|
||||
[],
|
||||
|
||||
Reference in New Issue
Block a user