You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Sanctum结合Spatie权限:配置用户与管理员权限

解决方案

1. 先修复令牌生成的错误

你当前生成令牌时传入了二维数组,这会导致Sanctum的权限验证异常。$user->getRoleNames()->toArray()本身已经是一维数组(比如['user']),不需要再嵌套一层数组。修改代码如下:

$user->createToken($user->name, $user->getRoleNames()->toArray())->plainTextToken;

2. 配置Spatie角色权限中间件

确保Spatie的Laravel Permission包已完成安装迁移,然后在app/Http/Kernel.php的$routeMiddleware中注册角色中间件:

'role' => \Spatie\Permission\Middlewares\RoleMiddleware::class,

3. 用Policy实现细粒度权限控制

这种方式能精准控制每个操作的权限,适配你需要的「user仅能操作自身,admin可操作所有」的场景。

生成User Policy

执行命令创建对应模型的Policy:

php artisan make:policy UserPolicy --model=User

编写Policy逻辑

打开app/Policies/UserPolicy.php,添加以下权限判断:

<?php

namespace App\Policies;

use App\Models\User;

class UserPolicy
{
    // 查看用户信息权限
    public function view(User $user, User $targetUser)
    {
        return $user->hasRole('admin') || $user->id === $targetUser->id;
    }

    // 更新用户信息权限
    public function update(User $user, User $targetUser)
    {
        return $user->hasRole('admin') || $user->id === $targetUser->id;
    }

    // 删除用户权限(按需添加)
    public function delete(User $user, User $targetUser)
    {
        return $user->hasRole('admin');
    }
}

注册Policy

在app/Providers/AuthServiceProvider.php的$policies数组中绑定Policy和模型:

protected $policies = [
    \App\Models\User::class => \App\Policies\UserPolicy::class,
];

在控制器中应用授权

在UserController的对应方法里调用authorize方法,触发权限验证:

// 查看单个用户
public function show(User $user)
{
    $this->authorize('view', $user);
    return response()->json($user);
}

// 更新用户信息
public function update(Request $request, User $user)
{
    $this->authorize('update', $user);
    $user->update($request->validated());
    return response()->json($user);
}

4. 可选:路由层面的权限分流

如果想直接在路由层限制角色访问范围,可以拆分路由:

Route::middleware('auth:sanctum')->group(function () {
    // admin专属:完整操作所有用户
    Route::middleware('role:admin')->group(function () {
        Route::apiResource('users', UserController::class);
    });

    // user专属:仅能操作自身信息
    Route::middleware('role:user')->group(function () {
        Route::get('users/me', [UserController::class, 'showMe']);
        Route::put('users/me', [UserController::class, 'updateMe']);
    });
});

然后在UserController中添加两个方法:

public function showMe()
{
    return response()->json(auth()->user());
}

public function updateMe(Request $request)
{
    $user = auth()->user();
    $user->update($request->validated());
    return response()->json($user);
}

这样user角色无法访问/users/{id}这类接口,只能通过/users/me操作自身数据,避免越权访问。

内容的提问来源于stack exchange,提问作者Hopex Development

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 10:12:14