Magento 管理员中的自定义控制器无需登录?
Custom controller in Magento's admin without login?
我正在尝试覆盖 Adminhtml 的 IndexController,来源如下:
class T2_AjaxAdmin_Adminhtml_IndexController extends Mage_Adminhtml_IndexController
{
/**
* Administrator ajax login action
*/
public function ajaxAction()
{
$jsonData = array();
$this->getResponse()->setHeader('Content-type', 'application/json');
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($jsonData));
exit();
}
}
我的配置文件
<?xml version="1.0"?>
<config>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<T2_AjaxAdmin before="Mage_Adminhtml">T2_AjaxAdmin_Adminhtml</T2_AjaxAdmin>
</modules>
</args>
</adminhtml>
</routers>
</admin>
</config>
我刚刚发现,任何从 Adminhtml 扩展的控制器都会首先重定向到登录页面。
我该怎么做才能防止这种情况发生?
您可能需要查看 app/code/core/Mage/Admin/Model/Observer.php
,它可能会限制 'open action' 的列表(无需登录)。
您必须查看第 51 行:
$requestedActionName = $request->getActionName();
$openActions = array(
'forgotpassword',
'resetpassword',
'resetpasswordpost',
'logout',
'refresh' // captcha refresh
);
if (in_array($requestedActionName, $openActions)) {
$request->setDispatched(true);
}
稍后在同一个文件中,他们还会检查参数 forwarded
,因此根据该参数,您可以欺骗 Magento 并在无需登录的情况下访问我们的控制器。
所以我刚刚为您做了检查,这对我来说很有效:
class B_Enoit_TestController extends Mage_Adminhtml_Controller_Action
{
public function preDispatch ()
{
Mage::app ()->getRequest ()->setParam ( 'forwarded', true );
return parent::preDispatch ();
}
public function indexAction ()
{
die ( 'I am in without login' );
}
}
所以根据这个文件的内容你要知道这只是一个绕过app/code/core/Mage/Admin/Model/Observer.php
深入了解:
public function actionPreDispatchAdmin($observer)
{
// some code I omit for shorten purpose
$request = Mage::app()->getRequest();
$user = $session->getUser();
$requestedActionName = $request->getActionName();
$openActions = array(
'forgotpassword',
'resetpassword',
'resetpasswordpost',
'logout',
'refresh' // captcha refresh
);
// so this test the current action against the list of open actions, which don't have to redirect to login, as seen above
if (in_array($requestedActionName, $openActions)) {
$request->setDispatched(true);
} else {
if($user) {
$user->reload();
}
// So after reloading the user, it checks if this admin user really exists
if (!$user || !$user->getId()) {
// this below condition test if we come from the login page and if we are currently trying to log in
if ($request->getPost('login')) {
// some code I omit for shorten purpose
}
// This test the query param forwarded so it is from reading this line that I created my working example
if (!$request->getParam('forwarded')) {
// some code I omit for shorten purpose
}
}
}
$session->refreshAcl();
}
看起来他们把它放在适当的位置,可以像您尝试的那样通过 json 或 ajax 访问管理数据,所以我认为这是适合您的方法.
您必须了解控制器 preDispatch
中的 Mage::app ()->getRequest ()->setParam ('param','value')
就像假装将其作为查询参数传递一样。
确实,如果您尝试访问这样的控制器:
class B_Enoit_TestController extends Mage_Adminhtml_Controller_Action
{
public function indexAction ()
{
die ( 'I am in without login' );
}
}
通过 url http://www.example.com/admin/test/index/forwarded/1/ 它会起作用,即使扩展 Mage_Adminhtml_Controller_Action
也不会将您重定向到登录名
我正在尝试覆盖 Adminhtml 的 IndexController,来源如下:
class T2_AjaxAdmin_Adminhtml_IndexController extends Mage_Adminhtml_IndexController
{
/**
* Administrator ajax login action
*/
public function ajaxAction()
{
$jsonData = array();
$this->getResponse()->setHeader('Content-type', 'application/json');
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($jsonData));
exit();
}
}
我的配置文件
<?xml version="1.0"?>
<config>
<admin>
<routers>
<adminhtml>
<args>
<modules>
<T2_AjaxAdmin before="Mage_Adminhtml">T2_AjaxAdmin_Adminhtml</T2_AjaxAdmin>
</modules>
</args>
</adminhtml>
</routers>
</admin>
</config>
我刚刚发现,任何从 Adminhtml 扩展的控制器都会首先重定向到登录页面。
我该怎么做才能防止这种情况发生?
您可能需要查看 app/code/core/Mage/Admin/Model/Observer.php
,它可能会限制 'open action' 的列表(无需登录)。
您必须查看第 51 行:
$requestedActionName = $request->getActionName();
$openActions = array(
'forgotpassword',
'resetpassword',
'resetpasswordpost',
'logout',
'refresh' // captcha refresh
);
if (in_array($requestedActionName, $openActions)) {
$request->setDispatched(true);
}
稍后在同一个文件中,他们还会检查参数 forwarded
,因此根据该参数,您可以欺骗 Magento 并在无需登录的情况下访问我们的控制器。
所以我刚刚为您做了检查,这对我来说很有效:
class B_Enoit_TestController extends Mage_Adminhtml_Controller_Action
{
public function preDispatch ()
{
Mage::app ()->getRequest ()->setParam ( 'forwarded', true );
return parent::preDispatch ();
}
public function indexAction ()
{
die ( 'I am in without login' );
}
}
所以根据这个文件的内容你要知道这只是一个绕过app/code/core/Mage/Admin/Model/Observer.php
深入了解:
public function actionPreDispatchAdmin($observer)
{
// some code I omit for shorten purpose
$request = Mage::app()->getRequest();
$user = $session->getUser();
$requestedActionName = $request->getActionName();
$openActions = array(
'forgotpassword',
'resetpassword',
'resetpasswordpost',
'logout',
'refresh' // captcha refresh
);
// so this test the current action against the list of open actions, which don't have to redirect to login, as seen above
if (in_array($requestedActionName, $openActions)) {
$request->setDispatched(true);
} else {
if($user) {
$user->reload();
}
// So after reloading the user, it checks if this admin user really exists
if (!$user || !$user->getId()) {
// this below condition test if we come from the login page and if we are currently trying to log in
if ($request->getPost('login')) {
// some code I omit for shorten purpose
}
// This test the query param forwarded so it is from reading this line that I created my working example
if (!$request->getParam('forwarded')) {
// some code I omit for shorten purpose
}
}
}
$session->refreshAcl();
}
看起来他们把它放在适当的位置,可以像您尝试的那样通过 json 或 ajax 访问管理数据,所以我认为这是适合您的方法.
您必须了解控制器 preDispatch
中的 Mage::app ()->getRequest ()->setParam ('param','value')
就像假装将其作为查询参数传递一样。
确实,如果您尝试访问这样的控制器:
class B_Enoit_TestController extends Mage_Adminhtml_Controller_Action
{
public function indexAction ()
{
die ( 'I am in without login' );
}
}
通过 url http://www.example.com/admin/test/index/forwarded/1/ 它会起作用,即使扩展 Mage_Adminhtml_Controller_Action