나는 다음과 같은 계획을 사용합니다. 대부분의 사용자 권한 확인은 두 가지 일반적인 경우로 나눌 수 있습니다.
- 매개 변수를 확인하지 않고 사용자 역할에 따라 컨트롤러 작업에 대한 사용자 액세스
- 특정 사용자와 특정 모델 간의 관계 또는 논리를 기반으로 모델에 대한 사용자 액세스.
속성을 확인하지 않고 컨트롤러 작업에 액세스하는 것은 일반적으로 MVC 프레임 워크에서 구현됩니다. 이것은 매우 간단합니다. 규칙을 정의하고 사용자에게 역할이 있습니다. 사용자에게 규칙에서 역할을 조회 할 수있는 권한이 있는지 확인하기 만하면됩니다.
특정 모델에 대한 사용자 액세스는 모델에서 정의해야합니다. 액터는 기본 사용자 클래스입니다. 고객, 판매자 또는 손님 일 수 있다고 가정하십시오.
interface ICheckAccess
{
public function checkAccess(Actor $actor, $role);
}
class SomeModel implements ICheckAccess
{
public function checkAccess(Actor $actor, $role)
{
// Your permissions logic can be as sophisticated as you want.
}
}
이 논리를 모델에 배치하면 약간의 이익이 발생합니다. 액세스 확인 방법을 상속받을 수 있으며 추가 클래스를 만들 필요가 없으며 일반적인 OOP 이점을 사용할 수 있습니다.
다음으로 액세스 확인을 단순화하기 위해 단순성과 좋은 스타일을 위해 거의 항상 구현 된 몇 가지 가정을 가정합니다.
- 일반적으로 컨트롤러는 일부 모델 클래스와 관련이 있습니다.
- 액세스가 확인 된 작업은 단일 모델 ID를 매개 변수로 사용합니다.
- 이 파라미터는 항상 기본 컨트롤러 클래스의 메소드에서 균일하게 액세스 할 수 있습니다.
- id 액션이 취하는 모델에 대응하는 액션이 컨트롤러에 배치됩니다.
이러한 가정을 통해 모델 ID를 사용하는 조치는 특정 모델 인스턴스와 연관 될 수 있습니다. 실제로 대부분의 작업은 위에서 설명한 가정에 맞게 쉽게 변환하고 이동할 수 있습니다.
그런 다음 일부 기본 추상 컨트롤러 클래스를 정의하고 상속해야합니다.
abstract class ModelController
{
// Retrieve model from database using id from action parameter.
public abstract function loadModel($id);
// Returns rules for user role to pass to SomeModel::checkAccess()
// Something like array('view' => 'viewer', 'delete' => 'owner', 'update' => 'owner')
public abstract function modelRules();
public abstract fucntion getIdParameter();
public function filterModelAccess()
{
$id = $this->getIdParameter();
if(!$this->checkModelAccess($id))
throw new HttpException(403);
}
public function checkModelAccess($id)
{
$model = $this->loadModel($id);
$actor = My::app()->getActor();
$rules = $this->modelRules();
$role = $rules[My::app()->getActionName()];
return $model->chechAccess($actor, $role);
}
}
메뉴를 구성하고 링크 표시 여부를 결정할 때 SomeController :: checkModelAccess ($ id) 메소드를 호출 할 수 있습니다.