我們最近開始改善組織,減少重複建設,除其他事項外,努力使用學說2.2,和Zend框架2的部分。今天,我開始討論實現服務層的想法,以充當我們的控制者和主體實體之間的中介。數據訪問和安全
目前,我國大多數邏輯駐留在控制器中。另外,我們使用動作助手來測試某些權限;然而,在實現Zend \ Di之後,我想出了一個新的方法。我開始創建特定於實體的服務模型,它使用Zend \ Di來注入一個EntityManager實例以及當前用戶的權限。
控制器代碼如下:
class Project_DeleteController extends Webjawns_Controller_Action
{
public function init()
{
$this->_initJsonContext();
}
public function indexAction()
{
$response = $this->_getAjaxResponse();
$auditId = (int) $this->_getParam('audit_id');
if (!$auditId) {
throw new DomainException('Audit ID required');
}
/* @var $auditService Service\Audit */
$auditService = $this->getDependencyInjector()->get('Service\Audit');
try {
$auditService->delete($auditId);
$response->setStatusSuccess();
} catch (Webjawns\Exception\SecurityException $e) {
$this->_noAuth();
} catch (Webjawns\Exception\Exception $e) {
$response->setStatusFailure($e->getMessage());
}
$response->sendResponse();
}
}
,我們的服務層中的一個的示例。構造函數接受兩個參數 - 一個接受EntityManager,另一個接受Zend \ Di注入的Entity \ UserAccess對象。
namespace Service;
use Webjawns\Service\Doctrine,
Webjawns\Exception;
class Audit extends AbstractService
{
public function delete($auditId)
{
// Only account admins can delete audits
if (\Webjawns_Acl::ROLE_ACCT_ADMIN != $this->getUserAccess()->getAccessRole()) {
throw new Exception\SecurityException('Only account administrators can delete audits');
}
$audit = $this->get($auditId);
if ($audit->getAuditStatus() !== \Entity\Audit::STATUS_IN_PROGRESS) {
throw new Exception\DomainException('Audits cannot be deleted once submitted for review');
}
$em = $this->getEntityManager();
$em->remove($audit);
$em->flush();
}
/**
* @param integer $auditId
* @return \Entity\Audit
*/
public function get($auditId)
{
/* @var $audit \Entity\Audit */
$audit = $this->getEntityManager()->find('Entity\Audit', $auditId);
if (null === $audit) {
throw new Exception\DomainException('Audit not found');
}
if ($audit->getAccount()->getAccountId() != $this->getUserAccess()->getAccount()->getAccountId()) {
throw new Exception\SecurityException('User and audit accounts do not match');
}
return $audit;
}
}
- 這是一個合適的模式來使用我們試圖完成?
- 它是很好的做法,在服務層內的權限驗證張貼?
- 據我所知,鑑於邏輯仍然駐留在所述控制器,使該模型的靈活性在各種情況下(JSON,XML,HTML等)來使用。思考?
我很滿意迄今爲止的工作方式,但如果有人看到我們如何做這件事的任何缺點,請張貼您的想法。
只是我的兩個認證便士。我不相信有一種正確的方式和一種錯誤的方式,但是,我開始將身份驗證放入服務層,但隨後將其移至我的控制器中。我的推理是服務層是我的內部API,我應該使用我的控制器層向全世界公開,因此它應該決定誰可以訪問什麼。另外,如果我想構建任何內部工具/腳本等,我不需要在它們中構建身份驗證來使用我的服務層。 – 2012-04-27 23:40:39
小心不要混淆身份驗證和訪問控制。在將任何域類引入圖片之前,身份驗證可以(應該?)進入模塊。只有你建立了用戶身份。例如:if(!$ authService-> hasIdentity())在您的域服務模型中。 – dualmon 2012-11-10 19:07:58
@JamieSutherland:我不同意。這些服務定義了業務邏輯;控制器是請求和適當業務邏輯之間的橋樑。例如,您只有一個服務來訂購產品,但您可能有多個控制器用於HTTP請求,API請求等等。如果您關心的是ACL請求特定(例如,通過HTTP,您可能期望用戶會話在哪裏,因爲您希望爲API請求提供密鑰),請概括一下您的ACL實現以實現此目的。 – moteutsch 2013-04-21 08:40:51