很抱歉这个问题很长,但我遇到了auth-> login()的问题,经过长时间的调试后,我想分享一下我的发现。这可能是我身边的蠢事,但请耐心等待......
模型“Cliente”(相关部分):
<?php
App::uses('AppModel', 'Model');
App::uses('BrValidation', 'Localized.Validation');
App::uses('AuthComponent', 'Controller/Component');
App::uses('SimplePasswordHasher', 'Controller/Component/Auth');
/**
* Cliente Model
*
*/
class Cliente extends AppModel {
public $primaryKey = 'idcliente';
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$passwordHasher = new SimplePasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}
}
ClientesController(相关部分):
<?php
App::uses('AppController', 'Controller');
App::uses('CakeEmail', 'Network/Email');
/**
* Clientes Controller
*
*/
class ClientesController extends AppController {
public $components = array('Paginator','RequestHandler');
/** beforeFilter
* Configura partes do sistema que podem ser acessadas sem login
*/
public function beforeFilter() {
//parent::beforeFilter();
//$this->Auth->allow();
}
public function login() {
//if already logged-in, redirect
if($this->Session->check('Auth.Cliente')){
$this->redirect(array('action' => 'index'));
}
// if we get the post information, try to authenticate
if ($this->request->is('post')) {
CakeLog::write('debug',"POS IF POST\n");
if ($this->Auth->login()) {
CakeLog::write('debug',"True no LOGIN\n");
$this->Session->setFlash(__('Welcome, '. $this->Auth->user('Cliente.username')));
$this->redirect($this->Auth->redirectUrl());
} else {
$this->Session->setFlash(__('Invalid username or password'));
}
}
}
AppController(相关部分) class AppController扩展了Controller {
public $components = array(
'DebugKit.Toolbar',
'Session',
'Auth' => array(
'loginAction' => array('controller' => 'clientes', 'action' => 'login'),
'loginRedirect' => array('controller' => 'clientes', 'action' => 'poslogin'),
'logoutRedirect' => array('controller' => 'clientes', 'action' => 'login'),
'authError' => 'Você precisa se logar para ver esta página.',
'loginError' => 'Usuário ou senha inválidos. Tente de novo.',
'authenticate' => array(
'Form' => array(
'userModel' => 'Cliente',
'fields' => array ( 'username' => 'username', 'password' => 'password')
)
)
));
无需发布关联的视图,因为表单会收集信息并按预期进行POST。
目前,无论POSTed数据如何,$ this-&gt; Auth-&gt; login()将始终返回TRUE。用户是否存在以及密码是否正确无关紧要。
Cake正在查找正确的表和正确的用户。我打开了MySQL General Log以确保实际查询是正确的,所以这里没有问题。
然后我转移到实际的Cake代码并找到以下内容。我们感兴趣的代码位于$ROOT/lib/Cake/Controller/Component/AuthComponent.php
,第595-607行(login()函数),位于:
public function login($user = null) {
$this->_setDefaults();
if (empty($user)) {
$user = $this->identify($this->request, $this->response);
}
if ($user) {
$this->Session->renew();
$this->Session->write(self::$sessionKey, $user);
}
CakeLog::write('debug',"LOGGEDIN:". $this->loggedIn());
return $this->loggedIn();
}
由于我们没有传递参数,Cake将尝试identify
用户(第599行),然后将返回其loggedIn
当前状态。 loggedIn
只是user()
调用的布尔结果,我们可以在第820-822行看到,所以让我们看看user()
(第648-658行)。
public static function user($key = null) {
if (!empty(self::$_user)) {
$user = self::$_user;
} elseif (self::$sessionKey && CakeSession::check(self::$sessionKey)) {
$user = CakeSession::read(self::$sessionKey);
} else {
CakeLog::write('debug',"return null");
return null;
}
if ($key === null) {
ob_start();
var_dump($user);
$d=ob_get_contents();
ob_clean();
CakeLog::write('debug',"return user: " . $d);
return $user;
}
CakeLog::write('debug',"return hash" . Hash::get($user,$key));
return Hash::get($user, $key);
}
由于我们在没有参数的情况下调用user()
,$key
将为NULL,代码将只是return $user
而且 - 至少对我来说 - 这就是问题所在。如果我var_dump($user)
如上所述,我得到一个空数组,但我得到一些“TRUE”并且登录过程“suceeeds”(当然是错误的)。
2014-05-25 00:24:04 Debug: return user: array(1) {
["Cliente"]=>
array(3) {
["idcliente"]=>
NULL
["username"]=>
NULL
["password"]=>
NULL
}
}
我正在使用Cake 2.4.1,但是我已经检查了所有2.4版本,直到2.4.10并且代码没有改变,所以这将在整个Cake 2.4中发生。我没有查找其他次要版本。我在OSX上运行PHP 5.5.3,但这对我来说听起来并不太重要。
我没有阅读任何提出此问题的ChangeLogs,并且在此问题上有一些未解决的问题。
我不想在没有共享的情况下更改核心代码,并且不确定SO是否是发布此内容的“正确”位置,而且很可能是我只是忽略了某些内容。
如果有人能够发表一些看法并表达一些想法,那将非常感激。
谢谢!
答案 0 :(得分:6)
我已经设法缩小了问题的范围,虽然核心代码中似乎没有错误,但它似乎有资格作为进一步调查的行为。
假设你有一个&#34;清洁&#34;浏览器会话,没有会话COOKIES。在这种情况下,代码将按预期工作。错误的用户和/或密码将被拒绝。
但是,一旦你登录,Cake会在浏览器中处理一个会话cookie(CAKEPHP),除其他信息外,它会将该会话链接到登录用户。
如果您尝试再次登录(&#34;在当前登录的基础上&#34;),$this->Auth->login()
(不带参数)无论如何都将产生TRUE。如果您提供了错误的用户/密码,它将坚持当前有效的用户/密码。如果您提供有效的用户/密码,它将更改为新用户。
除非您退出,或者会话cookie过期(或者您手动删除它),否则无论您是否使用参数调用$this->Auth->login()
都无关紧要。
从一个&#34;页面流&#34; /逻辑角度来看,它似乎是有意义的(从用户行为的角度来看,为什么会在登录后调用&#34;登录&#34; AGAIN?)这可能导致(如此处注意到的!)奇怪的问题。
让我们说你登录,做你想做的任何事情并离开你的网络应用程序而不退出。您将在Cake会话Cookie的持续时间内保持登录状态。如果您与其他人共享浏览器和应用程序,此人可能会意外地使用您的帐户,登录但输入密码错误,在这种情况下,如上所述,login()
将返回TRUE,但WON&#39 ; T CHANGE用户。更不用说,潜在的恶意用途。
无论如何......在登录之前强行$this->Auth->logout()
可能是一种好习惯,以避免潜在的应用程序错误行为。
由于这种方法似乎贯穿Cake 2.x,我希望我的问题也能澄清其他人。