使用UsersController登录失败,提示‘用户名或密码错误’技术求助
Hey there, let's work through fixing that frustrating "Invalid username or password" error you're hitting with your CakePHP login system. Based on the files you mentioned, here are the key checks and fixes to implement:
First, make sure your UsersTable.php is correctly handling password hashing on save. The most common issue here is either the hashing callback not triggering, or incorrect hasher setup.
Here's a working example of what your table should look like:
// src/Model/Table/UsersTable.php namespace App\Model\Table; use Cake\ORM\Table; use Cake\Auth\DefaultPasswordHasher; use Cake\Event\EventInterface; use Cake\Datasource\EntityInterface; use ArrayObject; class UsersTable extends Table { public function initialize(array $config): void { parent::initialize($config); $this->addBehavior('Timestamp'); } public function beforeSave(EventInterface $event, EntityInterface $entity, ArrayObject $options) { // Only hash the password if it's been modified (prevents re-hashing on updates) if ($entity->isDirty('password')) { $hasher = new DefaultPasswordHasher(); $entity->set('password', $hasher->hash($entity->get('password'))); } return true; } }
- Critical Check: Ensure your password validation rules don't restrict length (e.g., no
maxLengthrules shorter than 60 characters—bcrypt hashes are 60 chars long, and your text field can handle this easily). - Also confirm that new users are storing hashed passwords in the database (not plaintext). If you see plaintext passwords, your
beforeSavecallback isn't firing.
The Auth component is the backbone of your login system, and misconfiguration here is a top culprit for login failures. Make sure you're telling it to use email as the identity field, and matching the password hasher to what you use in UsersTable.
Update your AppController.php like this:
// src/Controller/AppController.php namespace App\Controller; use Cake\Controller\Controller; class AppController extends Controller { public function initialize(): void { parent::initialize(); $this->loadComponent('Flash'); $this->loadComponent('Auth', [ 'authenticate' => [ 'Form' => [ // Map the login form fields to your database columns 'fields' => [ 'username' => 'email', // This is key—use email instead of default username 'password' => 'password' ], // Match the hasher to your UsersTable setup 'passwordHasher' => [ 'className' => 'Default', 'hashType' => 'bcrypt' ] ] ], 'loginAction' => [ 'controller' => 'Users', 'action' => 'login' ], 'loginRedirect' => [ 'controller' => 'Pages', 'action' => 'display', 'home' ], 'logoutRedirect' => [ 'controller' => 'Users', 'action' => 'login' ] ]); } }
- Don't Skip This: If you leave
usernameset to the default value, Auth will look for ausernamecolumn in your users table (which you don't have), leading to the "invalid credentials" error every time.
Your login action should be straightforward—make sure you're not overcomplicating it or modifying the request data incorrectly.
Here's a clean version of the login method:
// src/Controller/UsersController.php namespace App\Controller; use App\Controller\AppController; use Cake\Auth\DefaultPasswordHasher; class UsersController extends AppController { public function login() { if ($this->request->is('post')) { // Let Auth handle identifying the user $user = $this->Auth->identify(); if ($user) { $this->Auth->setUser($user); return $this->redirect($this->Auth->redirectUrl()); } // The error message users see—match this to what you're displaying $this->Flash->error(__('Invalid email or password, please try again.')); } } // Rest of your controller methods (add, edit, etc.)... }
If you're still stuck, add debug lines to troubleshoot:
// Inside the login action's post block $data = $this->request->getData(); debug($data); // Check if email/password are being submitted correctly $user = $this->Users->findByEmail($data['email'])->first(); if ($user) { $hasher = new DefaultPasswordHasher(); debug($hasher->check($data['password'], $user->password)); // Will output true/false to confirm password match }
This will tell you if the issue is a missing user record, or a password hash mismatch.
Your login form must send the right field names to match your Auth configuration. Double-check login.ctp:
<!-- templates/Users/login.ctp --> <div class="users form"> <?= $this->Form->create() ?> <fieldset> <legend><?= __('Log In') ?></legend> <!-- Field name must be "email" (matches Auth's username field setting) --> <?= $this->Form->control('email', ['label' => 'Email Address']) ?> <?= $this->Form->control('password', ['label' => 'Password']) ?> </fieldset> <?= $this->Form->button(__('Sign In')) ?> <?= $this->Form->end() ?> </div>
- Common Mistake: Using
name="username"instead ofname="email"here will cause Auth to never find the correct user.
Ensure your password column is set to TEXT (which you mentioned it is) and that it's not truncating the hash. Bcrypt hashes are 60 characters long, so even a VARCHAR(255) would work, but TEXT is totally fine.
内容的提问来源于stack exchange,提问作者Javed Saifi

