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

Laravel多作者权限校验代码冗余问题及优化方案咨询

Clean Up Author Ownership Validation in Laravel

Hey there! I totally get it—repeating that author ID ownership check in every controller action feels messy and violates the DRY (Don't Repeat Yourself) principle. Let's fix this with a few clean, Laravel-native approaches depending on your needs.

Option 1: Enhance Your author Middleware to Handle Ownership

The quickest win is to move that controller validation logic directly into your middleware. This way, every route in your auth + author group will automatically validate that the author ID belongs to the authenticated user—no redundant controller code needed.

Here's the updated middleware code:

public function handle($request, Closure $next) {
    // First, confirm user is logged in
    if (!auth()->check()) {
        return redirect('/dashboard')->with("error", "Please log in first");
    }

    $user = auth()->user();

    // Keep your original check for existing author profiles
    if ($user->authorsProfile->isEmpty()) {
        return redirect('/dashboard')->with("error", "Only Authors Allowed");
    }

    // Add ownership validation for the requested author ID
    if (isset($request->id)) {
        $author = Author::find($request->id);
        if (!$author || $author->user_id !== $user->id) {
            return back()->with("error", "This Author is not you");
        }
    }

    return $next($request);
}

With this change, you can completely remove the ownership check from your controller:

public function dashboard($id) {
    // No validation needed here—middleware already handled it
    return view('frontend.author.dashboard');
}

Option 2: Use Route Model Binding with User Scoping

For an even more elegant solution, leverage Laravel's route model binding. This lets Laravel automatically fetch the Author model for you, and we can add a scope to ensure it only returns authors belonging to the current user.

First, update your route to use model binding (replace {id} with {author}):

Route::group(['middleware' => ['auth','author']], function() {
    Route::get('authorsarea/{author}','AuthorController@dashboard')->name('author-dashboard');
});

Next, add a global scope to your Author model to restrict queries to the authenticated user:

// In your Author model
protected static function booted()
{
    static::addGlobalScope('user', function ($query) {
        if (auth()->check()) {
            $query->where('user_id', auth()->id());
        }
    });
}

Alternatively, if you don't want a global scope, define a custom route binding in your RouteServiceProvider:

// In RouteServiceProvider@boot
Route::bind('author', function ($value) {
    return Author::where('id', $value)
        ->where('user_id', auth()->id())
        ->firstOrFail();
});

Now your controller can directly accept the Author model—Laravel will automatically throw a 404 if the author doesn't exist or doesn't belong to the user:

public function dashboard(Author $author) {
    // $author is guaranteed to belong to the current user
    return view('frontend.author.dashboard', compact('author'));
}

Option 3: Extract Validation to a Reusable Trait

If you only need this validation in specific controller actions (not the entire middleware group), create a trait to reuse the logic:

// app/Http/Controllers/Traits/ValidatesAuthorOwnership.php
namespace App\Http\Controllers\Traits;

use App\Models\Author;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\RedirectResponse;

trait ValidatesAuthorOwnership
{
    protected function validateAuthorOwnership($authorId): Author|RedirectResponse
    {
        $author = Author::find($authorId);
        
        if (!$author || $author->user_id !== Auth::id()) {
            return back()->with("error", "This Author is not you");
        }
        
        return $author;
    }
}

Then use it in your controller:

use App\Http\Controllers\Traits\ValidatesAuthorOwnership;

class AuthorController extends Controller
{
    use ValidatesAuthorOwnership;

    public function dashboard($id) {
        $author = $this->validateAuthorOwnership($id);
        if ($author instanceof RedirectResponse) {
            return $author;
        }

        return view('frontend.author.dashboard', compact('author'));
    }
}

Which Option Should You Pick?

  • Middleware: Ideal if every route in your author group needs ownership validation. Keeps controllers clean and centralized.
  • Route Model Binding: The most Laravel-idiomatic approach, especially if you need to work with the Author model in your controller.
  • Trait: Perfect for one-off controller actions where you don't want to apply validation across an entire route group.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:29:52