我的应用程序有3种不同的场景:
前两个场景由简单的过滤器处理,并且由于所有场景在逻辑上都相似,所以剩下的场景似乎也应该由过滤器处理。
那么,我想做什么:
当用户访问某些特定的控制器操作(即HomeController@getIndex
)时,过滤器应检查用户是否被授权,将控制器的$user
属性设置为Auth::user()
值并分享所有视图之间的值。这是我提出的代码:
Router::filter('auth', function() {
$route = Str::parseCallback(Route::currentRouteAction(), null); // 0 - controller name, 1 - controller action name
$controller = App::make($route[0]);
$user = Auth::user();
$controller->user = $user;
View::share('user', $user);
return $controller->{$route[1]}();
});
此代码有效,但控制器被调用两次(即当控制器操作没有return
构造时),并且auth过滤器在调用任何其他'before'
过滤器之前调用控制器。
第二个解决方案:
创建AuthController
,并使用它的构造函数来设置$user
属性,但是每个子控制器操作都会调用构造函数(我只想在特定的操作上运行它,所以我认为过滤器是要走的路。)
第三种解决方案:
创建UserRepository
并编写一个方法,该方法将执行所有auth内容,并从需要auth(不设置$user
属性)的操作中调用它。对于几行代码来说,这个解决方案似乎有点过头了。
第四个解决方案:
直接将Auth::user()
值传递给控制器操作(作为参数),但我还没有找到任何方便的方法。
是否有任何"最佳做法"以描述的方式处理auth的解决方案? 有没有其他方法可以解决这个问题?
答案 0 :(得分:1)
最佳做法可能是为每个注入用户存储库的控制器创建一个UserRepository类和服务提供程序,但就像你说的那样,可能有些过于简单。
也许一个更简单的解决方案是向BaseController.php添加一个设置用户的函数。
public function setUser()
{
$this->user = Auth::user();
}
然后,只要您需要设置用户,只需致电$controller->setUser();
即可。如果您总是需要控制器来执行此操作,只需在构造函数中调用$this->setUser()
,以便它始终可用。
答案 1 :(得分:1)
感谢@ user3158900我做了一些研究并提出了另一个解决方案。
由于在expose
模型中放置User
方法有点不直观,因此扩展授权外观似乎是正确的。
这是我的最终解决方案:
在app / extensions / Auth /目录中创建一个Guard类。这个类扩展了Laravel的本地Illuminate\Auth\Guard
类。
<?php namespace Extensions\Auth;
class Guard extends \Illuminate\Auth\Guard {
public function exposeUser() {
$user = \Auth::user();
\View::share('user', $user);
return $user;
}
}
在app目录中创建extensions.php文件,并将此文件包含到app / global / start.php中。
require app_path().'/filters.php';
require app_path().'/extensions.php';
新的extensions.php文件包含以下代码(此代码添加新的auth驱动程序):
Auth::extend('eloquent+', function() {
return new \Extensions\Auth\Guard(
new \Illuminate\Auth\EloquentUserProvider(App::make('hash'), \Config::get('auth.model')),
App::make('session.store')
);
});
将auth config的(app / config / auth.php)$model
属性设置为'eloquent+
'(这使我们的身份验证使用'eloquent+'
作为auth驱动程序。)
修改composer.json以反映新的自动加载类映射。
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/extensions"
]
},
最后运行composer dump-autoload
。
现在您可以像往常一样使用Auth :: user()和其他auth方法,此外我们可以在视图之间共享模型,并通过在控制器操作中调用Auth::exposeUser()
的任何操作来访问它。
获得有关此方法的一些反馈也很好。