在CakePHP中,如果没有循环重定向,如何重定向到captcha for x失败?

在CakePHP中,如果没有循环重定向,如何重定向到captcha for x失败?,php,cakephp,php-5.3,cakephp-1.3,Php,Cakephp,Php 5.3,Cakephp 1.3,我正在使用核心身份验证组件。我已经创建了一个管理所有权限的用户登录名。我实现登录监控的方法是在app\u控制器中检查$this->Auth->user()。每次应用程序控制器循环执行beforeFilter()函数和$这个->身份验证->用户(),它将增加Captcha.loginatests会话变量。当Captcha.loginatests为>3时,我希望它重定向到Captcha控制器,显示一个Captcha屏幕,要求用户确认他们是人。(类似于stackoverflow的工作方式) 我遇到的问

我正在使用核心身份验证组件。我已经创建了一个管理所有权限的用户登录名。我实现登录监控的方法是在app\u控制器中检查
$this->Auth->user()
。每次应用程序控制器循环执行
beforeFilter()
函数和
$这个->身份验证->用户()
,它将增加
Captcha.loginatests
会话变量。当
Captcha.loginatests
为>3时,我希望它重定向到Captcha控制器,显示一个Captcha屏幕,要求用户确认他们是人。(类似于stackoverflow的工作方式)

我遇到的问题是,如果我在页面上的某个地方使用某个元素或引用cake框架中的某个元素,它将命中重定向,并导致对实际控制器/操作外部调用的每个访问元素/组件进行无休止的循环重定向。有没有更好的方法来实现这一点

这是我一直在处理的实际代码。但它基本上很糟糕(IMO):


你可以看到我是如何避免循环引用的。但是用户可以直接进入登录页面,因为
Captcha.fail
会话变量已经设置,它将忽略重定向。必须有一种更优雅的方式来实现这一点。有人吗?

通常,我会尝试回答您尝试的方式,但既然您要求提供更好的想法,我会在登录页面上实际添加验证码,并使用AuthComponents内置方法和属性,如LoginDirect、autoRedirect和allow()。然后,只需根据Captchas.loginatests变量打开/关闭captcha

对于你目前的方法,我不认为你会得到一个优雅的方式来做这件事。但是,您可以更改AuthComponent的属性以获得所需的内容。您可以更改LoginDirect和loginAction,使/captchas/index成为新的登录表单,然后在成功验证码后,将loginAction设置回/users/login或其他。这样,如果有人试图在不执行验证码的情况下直接点击/users/login,则AuthComponent逻辑将启动并重定向到/captchas/index

以下是一些相关的手册页面:


希望这有帮助

为什么它在应用程序控制器中?你只是想控制登录吗?因为我会把它放在用户控制器中。我还将使用
$this->Session->check()
检查会话。您似乎从未将“Captcha.loginatests”初始化为0。默认值可能会得到它,但这可能就是原因。我想在app_控制器中使用它,这样它就可以与用户控制器解耦。(便携性)。我希望能够在全球范围内实现这一点(就像核心Auth组件那样)。但是我撞到了墙,我的大脑被卡住了。此外,我还打算使用它来快速抑制输入,以避免有人以编程方式访问表单。我应该采取另一种方法吗?“…以编程方式阻止某人访问表单”-使用安全组件。谢谢bancer!这无疑是寻求保护的途径。这也会消除验证码的需要吗?我喜欢auth重定向的想法。那就行了。我将实施并报告其工作原理。谢谢你的建议!不幸的是,$this->Auth->loginAction='';不会做我想做的-它只会以默认方式重定向未经验证的用户。因此,我无法改变这个中流(例如)以及三次失败的尝试现在如何路由到验证码/索引。但是谢谢你的主意。这是值得研究的。
// this is in the app_controller beforeFilter() method.

if($this->Auth->user()) {
            $this->Session->delete('Captcha');
        } else {
            $this->Session->write('Captcha.LoginAttempts', $this->Session->read('Captcha.LoginAttempts') + 1);
            if ($this->Session->read('Captcha.LoginAttempts') > 3) {
                if (!$this->Session->read('Captcha.controller')) {
                    $this->Session->write('Captcha.controller', $this->params['controller']);
                    $this->Session->write('Captcha.action', $this->params['action']);
                }
                if ($this->Session->read('Captcha.fail') !== 'true') { // avoid circular reference redirects
                    $this->Session->write('Captcha.fail', 'true');
                    $this->redirect(array('controller' => 'captchas', 'action' => 'index'));
                }
            }
        }