1

在我的设计中,一个操作有一个等级,需要 0-10 才能访问它(0 是访客 [未登录],10 是管理员)。每个用户都有一个等级,0-10。如果您有等级或更高的等级,您可以访问该操作,否则您不能。又好又简单,这就是我所需要的。

问题是 CakePHP 希望我用两个独立的概念来处理动作。我必须将它们标记为 Auth->allow/deny 以确定身份验证系统是否会打扰它们,然后我使用 isAuthorized() 控制对它们的访问。

isAuthorized 非常适合我的需求...除了我想要访问等级 0 的任何操作都必须是 Auth->allow()... 然后完全忽略我的 isAuthorized 方法。如果我拒绝所有页面,登录会在应该为 0 级的页面上触发,然后再检查 isAuthorized,因此即使我通过它授予授权,该人也必须先登录。

有没有办法将两个系统合并在一起,或者有一种简单的方法来替换它?大多数身份验证系统都很棒,可以为我处理业务,而无需我搞乱它......但这很尴尬,并且当我没有注意到混合的允许/拒绝或其他东西时会引起问题.

谢谢!

4

2 回答 2

4

据我所知,唯一的方法是创建一个来宾用户。这是因为 Auth 组件在isAuthorized()像您解释的那样之前检查用户的存在。

您可以通过直接写入会话来做到这一点。这将告诉 Auth 组件有人登录,因此isAuthorized()将调用您的方法。

应用控制器

public function beforeFilter() {
  // if no one is logged in, log in a guest
  if (!$this->Auth->user()) {
    $this->Session->write(AuthComponent::$sessionKey, array(
      'User' => array(
        'id' => 0
       )
    ));
  }
}

public function isAuthorized($user) {
  $authorized = false;
  if ($this->Auth->user('id') == 0) {
    // public guest user access
  }
  // other logic
  return $authorized;
}

一个可能更好的方法是使用自定义身份验证对象,它基本上告诉 Cake 使用该类来帮助进行身份验证。这会将逻辑拆分为一个单独的类,从而更容易测试甚至禁用。

应用程序/控制器/组件/Auth/GuestAuthenticate.php

App::uses('BaseAuthenticate', 'Controller/Component/Auth');

class GuestAuthenticate extends BaseAuthenticate {
    public function authenticate(CakeRequest $request, CakeResponse $response) {
        // no real authentication logic, just return a guest user
        return array('User' => array('id' => 0));
    }
}

应用控制器

public $components = array(
  'Auth' => array(
    'authenticate' => array(
      'Form',
      'Guest' // tell Cake to try Form authentication then Guest authentication
    )
  )
);

public function beforeFilter() {
  if (!$this->Auth->user()) {
    // no user? log in a guest (this will fail form authentication
    // then try guest authentication)
    $this->Auth->login();
  }
}

public function isAuthorized($user) {
  $authorized = false;
  if ($this->Auth->user('id') == 0) {
    // public guest user access
  }
  // other logic
  return $authorized;
}

您可以在此处找到有关自定义身份验证对象的更多信息:http: //book.cakephp.org/2.0/en/core-libraries/components/authentication.html

于 2012-04-24T14:39:16.067 回答
1

也许这已经得到了令人满意的处理,但我有一个解决方案。

在我的 AppController 中,我有以下内容:

    public function isAuthorized($user = null) {
        if (in_array($this->action, $this->Auth->allowedActions)) {
            return true;
        }
        return false;
    }

正如您所发现的,如果您没有明确授权操作,那么经过身份验证的用户将被拒绝,即使它们被允许公开。这段代码只是让 isAuthorized() 方法遵循 Auth->allow() 列表中的设置。

它似乎对我有用,所以我希望它有所帮助。

于 2012-05-12T22:20:23.277 回答