
本文旨在帮助开发者理解和解决 Laravel 框架中遇到的 "403 THIS ACTION IS UNAUTHORIZED" 错误。通过创建 Policy 类并在 AuthServiceProvider 中注册,我们可以细粒度地控制用户对特定资源的操作权限,确保只有授权用户才能执行敏感操作,从而保障应用安全。
Laravel 提供了强大的权限认证机制,允许开发者轻松地控制用户对应用程序资源的访问权限。当用户尝试访问未经授权的资源时,会抛出 "403 THIS ACTION IS UNAUTHORIZED" 错误。本文将详细介绍如何使用 Laravel 的 Policy 类来解决此问题,并提供示例代码。
1. 创建 Policy 类
Policy 类用于定义特定模型的操作权限规则。假设我们有一个 Profile 模型,我们需要定义只有 Profile 的所有者才能编辑和更新 Profile 信息的规则。首先,我们需要创建一个 ProfilePolicy 类:
php artisan make:policy ProfilePolicy --model=Profile
这将会在 app/Policies 目录下创建一个 ProfilePolicy.php 文件。
2. 定义权限规则
打开 ProfilePolicy.php 文件,并定义 update 方法,该方法用于判断用户是否有权更新 Profile 模型。
<?php
namespace App\Policies;
use App\Models\Profile;
use App\Models\User;
use Illuminate\Auth\Access\HandlesAuthorization;
class ProfilePolicy
{
    use HandlesAuthorization;
    /**
     * Determine whether the user can update the model.
     *
     * @param  \App\Models\User  $user
     * @param  \App\Models\Profile  $profile
     * @return \Illuminate\Auth\Access\Response|bool
     */
    public function update(User $user, Profile $profile)
    {
        return $user->id === $profile->user_id;
    }
}在这个例子中,update 方法接收当前用户 $user 和要更新的 Profile 模型 $profile 作为参数。如果用户的 ID 与 Profile 的 user_id 相匹配,则返回 true,表示用户有权更新 Profile。否则,返回 false,表示用户没有权限。
3. 注册 Policy 类
要让 Laravel 知道 ProfilePolicy 对应于 Profile 模型,需要在 AuthServiceProvider 中注册 Policy。打开 app/Providers/AuthServiceProvider.php 文件,并在 $policies 属性中添加以下内容:
<?php
namespace App\Providers;
use App\Models\Profile;
use App\Policies\ProfilePolicy;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array<class-string, class-string>
     */
    protected $policies = [
        Profile::class => ProfilePolicy::class,
    ];
    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        //
    }
}4. 在 Controller 中使用 Policy
现在,我们可以在 ProfilesController 中使用 authorize 方法来检查用户是否具有更新 Profile 的权限。
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class ProfilesController extends Controller
{
    public function edit(User $user)
    {
        $this->authorize('update', $user->profile);
        return view('profiles.edit', compact('user'));
    }
    public function update(User $user)
    {
        $this->authorize('update', $user->profile);
        $data = request()->validate([
            'title' => 'required',
            'description' => 'required',
            'url' => 'url',
            'image' => '',
        ]);
        auth()->user()->profile->update($data);
        return redirect("/profile/{$user->id}");
    }
}在 edit 和 update 方法中,我们调用了 $this->authorize('update', $user->profile)。Laravel 会自动查找与 Profile 模型关联的 ProfilePolicy 类,并调用 update 方法。如果用户没有权限,authorize 方法会抛出 AuthorizationException,并返回 "403 THIS ACTION IS UNAUTHORIZED" 错误。
5. 异常处理
为了更好地处理 AuthorizationException,可以在 app/Exceptions/Handler.php 文件中添加以下代码:
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
use Illuminate\Auth\Access\AuthorizationException;
use Symfony\Component\HttpFoundation\Response;
class Handler extends ExceptionHandler
{
    /**
     * A list of the exception types that are not reported.
     *
     * @var array<int, class-string<Throwable>>
     */
    protected $dontReport = [
        //
    ];
    /**
     * A list of the inputs that are never flashed to the session on validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];
    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //
        });
        $this->renderable(function (AuthorizationException $e, $request) {
            return response()->view('errors.403', [], Response::HTTP_FORBIDDEN);
        });
    }
}这段代码会在抛出 AuthorizationException 时,渲染一个自定义的 errors.403 视图,向用户显示更友好的错误信息。你需要在 resources/views/errors 目录下创建一个 403.blade.php 文件。
总结与注意事项
通过以上步骤,可以有效地解决 Laravel 中的 "403 THIS ACTION IS UNAUTHORIZED" 错误,并实现细粒度的权限控制,从而提高应用程序的安全性。
以上就是Laravel 权限认证:解决 403 Unauthorized 错误的详细内容,更多请关注php中文网其它相关文章!
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
                Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号