【问题标题】:CakePhp Auth : QuestionsCakePhp 身份验证:问题
【发布时间】:2011-09-02 06:38:35
【问题描述】:

我要做一个 cakePhp 身份验证,我希望使用“Auth”组件。我正在尝试看看它是否满足我的要求:

  • 我需要使用他们的电子邮件或客户 ID 对用户进行身份验证(当然还有额外的密码)。我找不到是否可以有两个(或更多)字段可以进行身份​​验证

  • 我有几个部分需要进行身份验证。但我需要不同的粒度:

    • 对于某些事情,它是整个控制器不应该被访问(如果可能有例外(例如所有“用户”控制器,除了登录/注册操作)对于其他我真的需要它是整个控制器(例如购物车控制器)
    • 有时我需要只有某些操作不可用而不被记录
    • 有时我需要不显示视图的一部分(例如不显示登录元素)
  • 组件是否管理密码更改等操作?因为如果用户更改其密码,我需要他没有断开连接。

非常感谢您的帮助

【问题讨论】:

    标签: php authentication cakephp


    【解决方案1】:

    简短的回答是,是的,您可以执行这些操作,但在我看来,ACL 可能无法满足您的需求(但如果有任何机会,我也倾向于避免使用 ACL)。你的观点:

    • 正如 Ivo 建议的那样,您需要一个自定义的 UsersController::login() 方法来通过多个字段进行身份验证(如果您的身份验证模型不是 User,则使用适当的控制器)。如果 Auth 组件的登录方法失败,它会将控制权传递给您的自定义 login() 方法。这是我一直在从事的一个项目的 sn-p:

      function login() {
        # Allow login by either username (legacy) or email.
        # If no authenticated user exists at this point then the Auth
        # component's login() method has failed and control has been passed
        # here for any further handling. Since the expected credentials
        # (email and password) have failed we're going to check for
        # username and password.
        $user = $this->Auth->user();
        if( empty( $user ) && !empty( $this->Auth->data['User']['email'] ) && !empty( $this->Auth->data['User']['password'] ) ) {
          $user = $this->User->find(
            'first',
            array(
              'recursive'  => -1,
              'conditions' => array(
                'User.username' => $this->Auth->data['User']['email'],
                'User.password' => $this->Auth->data['User']['password'],
              )
            )
          );
      
          if( empty( $user ) || !$this->Auth->login( $user ) ) {
            # Set the configured flash message b/c login failed after both checks.
            $this->Session->setFlash( $this->Auth->loginError, null, array(), 'auth' );
          }
        }
      
        $this->redirect( $this->Auth->redirect(), null, true );
      }
      
    • 对于操作访问,只需在每个相关控制器的 beforeFilter() 回调中使用 $this->Auth->allow()$this->Auth->deny() 方法。例如,在UsersController 中,您可能想要执行以下操作:

      public function beforeFilter() {
        parent::beforeFilter();
      
        $this->Auth->deny('*');
        $this->Auth->allow( 'login', 'logout' );
      }
      
    • 在视图中,只需通过测试Auth.User 值来确定用户是否经过身份验证,以确定要显示/隐藏匿名/经过身份验证的内容:

      if( $this->Session->check( 'Auth.User' ) ) { ... }
      
    • 如果密码更改,您可以通过调用$this->Auth->login( $user_data ) 透明地重新验证用户。例如,当用户注册时,我会这样做。我不希望他/她必须然后登录,所以我只是自动登录。

    【讨论】:

    • 谢谢,有了这个,我已经足够朝着好的方向开始了
    【解决方案2】:

    Auth 并不能完全按照您的意愿开箱即用。它只能处理是否需要用户身份验证才能访问操作。用户登录后,Auth 不再关心用户的级别访问权限。

    如果您希望使用两个以上的字段,我建议您扩展 AuthComponent 并重写登录方法以满足您的需求。我从来没有这样做过,但我想这相当容易。

    关于您的访问级别,我会使用 ACL 来管理对所有控制器的操作的访问。设置完成后,您必须手动设置每个操作的权限,可以使用社区编写的插件之一,也可以手动设置。

    如果您希望禁用部分视图,则需要读取权限以从那里测试用户的访问级别。一件好事是在用户登录时将权限保存在缓存文件或会话中,以使其在视图中可用。然后编写您的测试并回显需要的内容。

    (我用的是CakePHP 2.0,不知道如果你在用的话,你在1.3中扩展AuthComponent有多么容易)

    【讨论】:

    • ACL 可能有点矫枉过正,我只需要“认证”与否
    【解决方案3】:

    使用 Auth,您需要恰好有 2 个字段(您可以指定)来进行身份验证。一个字段(密码)将被散列。是的,您想要的所有访问级别都可以在 Auth 中指定:http://book.cakephp.org/view/1251/Setting-Auth-Component-Variables

    您必须管理密码更改,但用户更改密码后不会退出。

    有时我需要不显示视图的一部分(例如不显示登录元素)

    哇?

    【讨论】:

    • 我认为他的意思是在视图中有一个 if 语句,如果用户通过身份验证,则只显示某个 HTML sn-p 等。我想你可以用 if (!$this->Auth->user()) { } 来做到这一点,但我不确定你如何让它更细化。
    • @Joseph : 没错,但我只需要知道用户是否经过身份验证,所以应该足够了
    【解决方案4】:

    创建一个自定义 login() 尝试通过任一方法进行身份验证。 您还可以设置Authenticate 变量来进行自定义登录。

    您可以在不同的控制器中指定 Auth 应该允许经过身份验证的用户的哪些部分。见Auth methods

    您还可以使用 ACL(请参阅完整的 Cake ACL 教程等)来控制细粒度的权限。

    有时我需要不显示视图的一部分

    创建一个元素来检查 Auth->user() 以选择要显示的内容。

    【讨论】:

      【解决方案5】:

      允许和拒绝部分可以通过 Auth 组件轻松完成。

      使用类似的东西

      $this->allow('*'); // to allow every thing
      $this->deny('*'); // to deny every thing
      $this->allow('login', 'signup'); // allows login and sign up without being logged in
      $this->deny('profile', 'password'); // need to be logged into to access profile and password and rest of the actions are allowed.
      

      对于密码的更改,您可以将更改后的密码保存到数据库中并强制注销用户并重定向他再次登录

      $this->Auth->logout(); this forces the user to logout of cakephp Auth
      

      对于第一个问题 - 使用 cakephp Auth 组件无法直接使用电子邮件或客户 ID 登录,因为您必须特别定义其中哪些充当用户名。

      替代解决方案是您可以将 Auth 组件复制到您的应用程序/控制器/组件中并破解代码。 收到用户名后,您可以根据电子邮件和客户 ID 对其进行测试并维护流程。

      希望对你有帮助

      【讨论】:

      • 这似乎是我需要的,但是这段代码必须在哪里?在每个控制器中?在相关的控制器中?在一个控制器的特定方法中?很遗憾,我们无法使用新凭据为自己进行 Auth->login()
      • 在控制器的 beforeFilter() 中添加这个。
      猜你喜欢
      • 1970-01-01
      • 2011-04-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多