How should I handle or improve my similar filters

2019-09-04 11:08发布

I have an application that I'm building in Laravel, this being the second time I've used it seriously. The application provides you the ability to log in and access certain areas of the site that guests/visitors may not have access to. This is pretty standard fare of every website with a signup option, and Laravel by default provides some standard ways to handle them with their already made filters:

// LARAVEL DEFAULT FILTER
Route::filter('auth', function()
{
    if (Auth::guest())
    {
        if (Request::ajax())
        {
            return Response::make('Unauthorized', 401);
        }
        else
        {
            return Redirect::guest('login');
        }
    }
});

My application takes this a step further and provides various permissions (you could also call them levels or roles), that a user can have. Sort of similar, but far less complicated than say, Stack Overflow. I am shimming an enum to represent these levels, with a higher number providing more access to areas others may not have:

abstract class UserRole {
    const Unauthenticated = 1;
    const Member = 2;
    const Subscriber = 3;
    const CharterSubscriber = 4;
    const Moderator = 5;
    const Administrator = 6;
}

Because of this, I've found myself setting up filters which are very similar to each other, and I feel like I'm violating DRY because of it. The filters check if you have the necessary permissions to access certain pages, like so:

Route::filter('mustBeMemberOrGreater', function() {
    if (Auth::guest() || Auth::user()->role_id < UserRole::Member) {
        return Redirect::home();
    }
});

Route::filter('mustBeSubscriberOrGreater', function() {
    if (Auth::guest() || Auth::user()->role_id < UserRole::Subscriber) {
        return Redirect::home();
    }
});

Route::filter('mustBeModeratorOrGreater', function() {
    if (Auth::guest() || Auth::user()->role_id < UserRole::Moderator) {
        return Redirect::home();
    }
});

// etc, etc

As you can see, they're all very similar to each other. Is there anyway I can wrap this functionality up into something less duplicative? All I know of is Laravel filters as I'm using them now. What other filter setup alternatives do I have at my disposal? Should I even be using filters, should this sort of logic be better in my Controllers?

All input is appreciated.

1条回答
对你真心纯属浪费
2楼-- · 2019-09-04 12:06

Filters are definitely the right choice, but you can make them more dynamic by passing parameters. Like so:

Route::group(array('before' => 'role:Member'), function(){
    // routes...
});

Here's how you set up that filter:

Route::filter('role', function($route, $request, $value){
    $role = constant('UserRole::'.$value);
    if (Auth::guest() || Auth::user()->role_id < $role) {
        return Redirect::home();
    }
});
查看更多
登录 后发表回答