zfcuser - 白名单路由和所有子路由
zfcuser - whitelist routes and all childroutes
我在我的应用程序中使用 ZfcUser 模块来保护对 /admin 路由的访问。因为我想阻止/admin 的所有子路由,除了/login、/register 等。
为此,我在此处添加了已接受答案的代码 - Zend Framework 2 - Global check for authentication with ZFCUser
protected $whitelist = array('zfcuser/login', 'default');
public function onBootstrap($e)
{
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$list = $this->whitelist;
$auth = $sm->get('zfcuser_auth_service');
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) {
$match = $e->getRouteMatch();
// No route match, this is a 404
if (!$match instanceof RouteMatch) {
return;
}
// Route is whitelisted
$name = $match->getMatchedRouteName();
if (in_array($name, $list)) {
return;
}
// User is authenticated
if ($auth->hasIdentity()) {
return;
}
// Redirect to the user login page, as an example
$router = $e->getRouter();
$url = $router->assemble(array(), array(
'name' => 'zfcuser/login'
));
$response = $e->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
return $response;
}, -100);
}
它有效,但它也会阻止对根路由的访问 - 由于它们很多,我真的不想将每条路由都添加到白名单。有什么方法可以限制只能访问 /admin 路由吗?
Is there any way to restrict access only to /admin routes?
这实际上意味着您需要 blacklist 而不是 whitelist 或更改条件检查的逻辑。
根据您的要求,您可以只检查部分路线,如下所示。
$this->whitelist = [
'zfcuser/login',
'default'
];
// Route is whitelisted
$currentRoute = $match->getMatchedRouteName();
foreach($this->whitelist as $route) {
if (0 === strpos($currentRoute, $route)) {
// we matched the start of the route,
// e.g every route under 'default' would match this
return;
}
}
您可以通过检查每个控制器名称而不是检查路由名称来保护对 admin 区域的访问。因此,您可以更轻松地控制用户的可访问性,并且比检查路由名称更便携。
列出您要限制访问的控制器。因此,与控制器相关的所有内容都应受到限制。无论您需要在何处限制访问,只需在此处列出即可。您无需再用 onBootstrap()
方法弄脏您的手了。
protected $whitelist = array(
'ZfcUser\Controller\User', // or use 'zfcuser'
);
在 $whitelist
中输入正确的控制器名称。您可以通过在 onBootstrap()
方法中回显 $controller
来获得它。请查看下面的评论区。
接下来找到控制器名称,然后检查它是否在您的列表中。
public function onBootstrap(MvcEvent $e)
{
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$list = $this->whitelist;
$auth = $sm->get('zfcuser_auth_service');
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) {
// get the current route
$route = $e->getRouteMatch()->getMatchedRouteName();
// check for 'zfcuser/login' and 'zfcuser/register' routes
if (in_array($route, array('zfcuser/login', 'zfcuser/register'))) {
return;
}
// get the current controller name
$controller = $e->getRouteMatch()->getParam('controller');
// Check the right controller name by echoing
// echo $controller;
// check if a user has access on the current controller
if (in_array($controller, $list)) {
if(! $auth->hasIdentity()) {
$router = $e->getRouter();
$url = $router->assemble(array(), array(
'name' => 'zfcuser/login'
));
$response = $e->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
return $response;
}
}
}, -100);
}
如果对您有帮助,请告诉我们!
我建议看一下 ZfcRbac。它有一个 "guards" functionality,我认为这正是您要找的:
return [
'zfc_rbac' => [
'guards' => [
'ZfcRbac\Guard\RouteGuard' => [
'admin*' => ['admin']
]
]
]
];
这会将任何以 admin
开头的路由限制为 admin
角色中的用户。由于默认的操作模式是基于黑名单的("protection mode" 是"allow"),您只需要为要限制访问的路由指定规则即可。任何不匹配 RouteGuard 的路由都将公开访问。
我在我的应用程序中使用 ZfcUser 模块来保护对 /admin 路由的访问。因为我想阻止/admin 的所有子路由,除了/login、/register 等。
为此,我在此处添加了已接受答案的代码 - Zend Framework 2 - Global check for authentication with ZFCUser
protected $whitelist = array('zfcuser/login', 'default');
public function onBootstrap($e)
{
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$list = $this->whitelist;
$auth = $sm->get('zfcuser_auth_service');
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) {
$match = $e->getRouteMatch();
// No route match, this is a 404
if (!$match instanceof RouteMatch) {
return;
}
// Route is whitelisted
$name = $match->getMatchedRouteName();
if (in_array($name, $list)) {
return;
}
// User is authenticated
if ($auth->hasIdentity()) {
return;
}
// Redirect to the user login page, as an example
$router = $e->getRouter();
$url = $router->assemble(array(), array(
'name' => 'zfcuser/login'
));
$response = $e->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
return $response;
}, -100);
}
它有效,但它也会阻止对根路由的访问 - 由于它们很多,我真的不想将每条路由都添加到白名单。有什么方法可以限制只能访问 /admin 路由吗?
Is there any way to restrict access only to /admin routes?
这实际上意味着您需要 blacklist 而不是 whitelist 或更改条件检查的逻辑。
根据您的要求,您可以只检查部分路线,如下所示。
$this->whitelist = [
'zfcuser/login',
'default'
];
// Route is whitelisted
$currentRoute = $match->getMatchedRouteName();
foreach($this->whitelist as $route) {
if (0 === strpos($currentRoute, $route)) {
// we matched the start of the route,
// e.g every route under 'default' would match this
return;
}
}
您可以通过检查每个控制器名称而不是检查路由名称来保护对 admin 区域的访问。因此,您可以更轻松地控制用户的可访问性,并且比检查路由名称更便携。
列出您要限制访问的控制器。因此,与控制器相关的所有内容都应受到限制。无论您需要在何处限制访问,只需在此处列出即可。您无需再用 onBootstrap()
方法弄脏您的手了。
protected $whitelist = array(
'ZfcUser\Controller\User', // or use 'zfcuser'
);
在 $whitelist
中输入正确的控制器名称。您可以通过在 onBootstrap()
方法中回显 $controller
来获得它。请查看下面的评论区。
接下来找到控制器名称,然后检查它是否在您的列表中。
public function onBootstrap(MvcEvent $e)
{
$app = $e->getApplication();
$em = $app->getEventManager();
$sm = $app->getServiceManager();
$list = $this->whitelist;
$auth = $sm->get('zfcuser_auth_service');
$em->attach(MvcEvent::EVENT_ROUTE, function($e) use ($list, $auth) {
// get the current route
$route = $e->getRouteMatch()->getMatchedRouteName();
// check for 'zfcuser/login' and 'zfcuser/register' routes
if (in_array($route, array('zfcuser/login', 'zfcuser/register'))) {
return;
}
// get the current controller name
$controller = $e->getRouteMatch()->getParam('controller');
// Check the right controller name by echoing
// echo $controller;
// check if a user has access on the current controller
if (in_array($controller, $list)) {
if(! $auth->hasIdentity()) {
$router = $e->getRouter();
$url = $router->assemble(array(), array(
'name' => 'zfcuser/login'
));
$response = $e->getResponse();
$response->getHeaders()->addHeaderLine('Location', $url);
$response->setStatusCode(302);
return $response;
}
}
}, -100);
}
如果对您有帮助,请告诉我们!
我建议看一下 ZfcRbac。它有一个 "guards" functionality,我认为这正是您要找的:
return [
'zfc_rbac' => [
'guards' => [
'ZfcRbac\Guard\RouteGuard' => [
'admin*' => ['admin']
]
]
]
];
这会将任何以 admin
开头的路由限制为 admin
角色中的用户。由于默认的操作模式是基于黑名单的("protection mode" 是"allow"),您只需要为要限制访问的路由指定规则即可。任何不匹配 RouteGuard 的路由都将公开访问。