I cannot login any users using AuthComponent.
The user table's name is users, with some important fields such as user_id, user_password, there is no hashing on the password field.
This is my AppController
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'home'),
'authError' => 'You cannot view this page',
'authorize' => array('controller')
)
);
public function isAuthorize($user) {
return true;
}
public function beforeFilter() {
$this->Auth->allow('home');
}
}
This is my UsersController
class UsersController extends AppController {
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Cannot login in');
}
}
}
}
This is my User model.
class User extends AppModel {
public $name = 'User';
public $primaryKey = 'user_id';
public $belongsTo = 'Group';
}
This is my View
<h2>Login</h2>
<?php
echo $this->Form->create();
echo $this->Form->input('user_id', array('label' => 'User ID', 'type' => 'text'));
echo $this->Form->input('user_password', array('label' => 'Password', 'type' => 'password'));
echo $this->Form->end('Login');
?>
When I typed corrected user_id and password then pressed the Login button, I got the message from the UsersController that I cannot login. What went wrong here???
Also, I really don't understand about the concept of AuthComponent:login(), how does it work to check user_id and password againt the database, how doest it know which field conttains user_id, and which one contains the password???
Please help.
Thanks.
Kongthap
A few things I noticed:
public function isAuthorize($user) {
This method is missing a 'd' on the end. It should be
public function isAuthorized($user) {
Next, by default, Cake expects to identify the user by fields named 'username' and 'password'. So, if you want to change that, you'll need to do this:
class AppController extends Controller {
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'users', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'home'),
'authError' => 'You cannot view this page',
'authorize' => array('controller'),
'authenticate' => array(
'Form' => array( // THIS IS WHERE YOU CHANGE THE DEFAULT FIELDS
'fields' => array('username' => 'user_id','password' => 'user_password')
)
)
)
);
That code isn't tested but should set you on the right track. But as Dave said, it's really worth reading through the complete doco to understand how it all works: http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html
Last, I'm not sure that 'user_id' is a good choice of column name. You'd expect a column name of 'user_id' to be a foreign key in some table, pointing to the 'id' column of a 'users' table. If that's not the function it serves, you should probably go with a different name.
Related
How to change user table name and column name for authentication in cakephp. By default its taking users as table name.
class AppController extends Controller {
public $components = array(
'Session','Security',
'Auth' => array(
'loginRedirect' => array('controller' => 'project', 'action' => 'index', 'Project Details'),
'logoutRedirect' => array('controller' => 'users', 'action' => 'login')
)
);
function beforeFilter() {
$this->Auth->allow('login');
}
}
Model :
App::uses('AppModel', 'Model');
class Users extends AppModel {
var $useTable = 'manager';
}
In your AppController's beforeFilter() method add following code
function beforeFilter(){
parent::beforeFilter();
$this->Auth->authenticate = array(
AuthComponent::ALL => array("fields" => array("username" => "your_username_column", "password" => "your_password_column") )
);
}
I'm using BotDetect Captcha in a CakePHP 2.6 application, and have implemented it as per the instructions on this page:
How To Add BotDetect Protection To CakePHP 2.6 Applications
The Captcha is working great on the controller/view where I need it.
However, it seems to be interfering somehow with the standard login process used by the same controller.
Here's my header for the controller which loads the BotDetect Component:
public $components = array('RequestHandler','Epd','BotDetect.Captcha' => array(
'CaptchaId' => 'EpdCaptcha',
'UserInputId' => 'CaptchaCode'));
Here's my login function:
public function login() {
$this->layout='login';
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirectUrl());
}
else
{
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
And here's my AppController.php:
class AppController extends Controller {
public $components = array(
'Auth' => array(
'loginRedirect' => array(
'controller' => 'users',
'action' => 'selectorg'
),
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login'
),
'authenticate' => array(
'Form' => array(
)
)
),
'Session'
);}
Now when I login to the app, the auth component isn't authorizing the login, and it's just bouncing back to the login screen. But when I remove the BotDetect component, the login works perfectly. I've tried changing the order of loading Components to see if that makes any difference... but to no avail.
Any suggestions?
Here is an example to integrate BotDetect Captcha component in cakephp 2.6 and it's working ok for me.
Controller: UsersController.php:
<?php
App::uses('AppController', 'Controller');
class UsersController extends AppController {
public $components = array(
'RequestHandler',
'BotDetect.Captcha' => array(
'CaptchaId' => 'EpdCaptcha',
'UserInputId' => 'CaptchaCode'
)
);
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('logout');
$this->Security->validatePost = false;
}
public function selectorg() {
echo 'selectorg';
$this->autoRender = false;
}
public function login() {
$this->set('captchaHtml', $this->Captcha->Html());
if ($this->request->is('post')) {
$isHuman = $this->Captcha->Validate($this->request->data['User']['CaptchaCode']);
unset($this->request->data['User']['CaptchaCode']);
if ($isHuman && $this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
} else {
if (!$isHuman) {
$this->Session->setFlash(__('CAPTCHA validation failed, try again.'));
} else {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
}
Controller: AppController.php:
class AppController extends Controller {
public $components = array(
'Security',
'Session',
'Auth' => array(
'loginRedirect' => array(
'controller' => 'users',
'action' => 'selectorg'
),
'logoutRedirect' => array(
'controller' => 'users',
'action' => 'login'
),
'authenticate' => array('Form' => array('passwordHasher' => 'Blowfish'))
)
);
}
View: login.ctp
<?php
echo $this->Html->css(CaptchaUrls::LayoutStylesheetUrl(), array('inline' => false));
echo $this->Form->create('User');
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Html->div('captcha', $captchaHtml, false);
// Captcha code user input textbox
echo $this->Form->input('CaptchaCode', array(
'label' => 'Retype the characters from the picture:',
'maxlength' => '10',
'style' => 'width: 300px;'
)
);
echo $this->Form->end('Submit');
?>
Model: User.php
<?php
App::uses('AppModel', 'Model');
App::uses('BlowfishPasswordHasher', 'Controller/Component/Auth');
class User extends AppModel {
public $name = 'User';
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter your username'
),
'unique' => array(
'rule' => 'isUnique',
'message' => 'Username already exists'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter your password'
)
)
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$passwordHasher = new BlowfishPasswordHasher();
$this->data[$this->alias]['password'] = $passwordHasher->hash(
$this->data[$this->alias]['password']
);
}
return true;
}
}
I'm trying to make a simple login system for my users, but I can't figure out why it won't log me in, the Auth->login() method always returns FALSE (incorrect information) for some reason... might be something with password hashing.
I have cakePHP 2.5.2.
Here is a screenshot of my issue: ISSUE
My beforeSave() method in UsersController:
public function beforeSave($options = array()) {
$this->request->data['User']['password'] = Security::hash($this->request->data['User']['password']);
}
and the login() method:
function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->Session->setFlash(__('You\'ve successfully logged in.' . ' <b>' . $this->Session->read('User.login') . '</b>'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-success'
), 'success');
return $this->redirect($this->Auth->redirectUrl());
//// $this->redirect($this->Auth->redirectUrl());
} else {
// var_dump($this->Auth->user());
$this->Session->setFlash(__('Sorry, the information you\'ve entered is incorrect.'), 'alert', array(
'plugin' => 'BoostCake',
'class' => 'alert-danger'
), 'danger');
}
}
}
here's the Auth component:
public $components = array(
'Session',
'Auth' => array(
'loginRedirect' => array('controller' => 'pages', 'action' => 'home'),
'logoutRedirect' => array('controller' => 'pages', 'action' => 'home'),
'loginAction' => array('controller' => 'users', 'action' => 'login'),
'authError' => 'You are not authorized to access this page.',
'authenticate' => array(
'Form' => array(
'userModel'=>'User',
'fields' => array(
'username' => 'login',
'password'=>'password')
)
),
'flash' => array(
'element' => 'alert',
'key' => 'auth',
'params' => array(
'plugin' => 'BoostCake',
'class' => 'alert-danger'
)
),'authorize'=>array('Controller'),
)
,'DebugKit.Toolbar'
);
Yes it's incorrect I removed everything and it works I don't know how
Move your beforeSave method to your Model, not the Controller.
When saving data Cake looks for any functions that should run before inserting the data in your Model.
You will also need to create a new user (if you look in your database you should find that the password has been stored as plaintext because the hashing in the beforeSave would never have been called.
I think you should provide the Security::hash() function blowfish or set the app's internal salt to true.
Like this:
public function beforeSave($options = array()) {
$this->request->data['User']['password'] = Security::hash($this->request->data['User']['password'], null, true);
}
This is the way, the deprecated AuthComponent::password() function works.
Just tested it this way in my Cake App and it work's fine.
See http://api.cakephp.org/2.4/class-Security.html#_hash
Edit:
beforeSave() should be in the User's Model, not in the User's Controller
I'm having some issues with the authentication component. Every time I try to login in with a user (I've checked that user exists in the database with correct params), my application throws me a failure login message.
I have two models, Accounts and Employees, where one Employee belongsTo Account, and one Account hasOne Employee. I save the data with saveAssociated(), and everything is ok in the database, but it's impossible to login.
I've been searching for solutions, and repeating the CookBook tutorials once and another, and I can't find what I'm doing wrong.
Here is some code:
class AppController extends Controller {
public $components = array(
'DebugKit.Toolbar',
'Session',
'Auth' => array(
'loginAction' => array('controller' => 'accounts', 'action' => 'login'),
'loginRedirect' => array('controller' => 'snippets', 'action' => 'index'),
'logoutRedirect' => array('controller' => 'snippets', 'action' => 'index'),
'authorize' => array('Controller')));
public function beforeFilter() {
$this->Auth->loginAction = array('controller' => 'accounts', 'action' => 'login');
$this->Auth->authenticate = array(
AuthComponent::ALL => array(
'userModel' => 'Account',
'fields' => array('username' => 'username', 'password' => 'password')),
'Basic',
'Form');
$this->Auth->allow('index', 'view');
My login function:
public function login() {
if($this->request->is('post')) {
if ($this->Auth->login()) {
$this->Session->setFlash(__('Welcome'));
return $this->redirect(array('controller' => 'snippets', 'action' => 'index'));
//return $this->redirect($this->Auth->redirect());
}
$this->Session->setFlash(__('Wrong password or email'), 'default', array(), 'auth');
}
}
Please, someone can tell me what I'm doing wrong? If you need to see some other code sections, tell me.
Thanks!
When Using ControllerAuthorize 'authorize' => array('Controller') you need to implement an isAuthorized() method that returns a boolean in your AppController.
public function isAuthorized($user = null) {
// Any registered user can access public functions
if (empty($this->request->params['admin'])) {
return true;
}
// Only admins can access admin functions
if (isset($this->request->params['admin'])) {
return (bool)($user['role'] === 'admin');
}
// Default deny
return false;
}
You can check the Auth Section of the docs the docs for more info, search for "Using ControllerAuthorize"
Sorry - Hate to ask but I've spent hour's working this out and researching but havent had any luck.
CakePHP (running the latest version) seems to refuse to use the fields setting (So that I can use the email column in the database as the username). If I set it to 'email' which is the field I wish to use from the database it simply refuses to login stating incorrect details. Cant get any output from SQL in DebugKit for some reason. Although when it's set to username as per below it works fine just using a 'temp' column in the DB. I've tried putting it in the components var but had no luck with that either. What could I be doing wrong? Debug is on, cant see any errors in the log or browser.
The model does contain an email column.
Controller/AppController.php
class AppController extends Controller {
public $components = array(
'Session',
'DebugKit.Toolbar',
'Auth' => array(
'allow' => array('login','logout'),
'loginAction' => array('controller' => 'users', 'action' => 'login'),
'loginRedirect' => array('controller' => 'dashboard', 'action' => 'index'),
'authorize' => 'Controller'
)
);
function beforeFilter() {
Security::setHash('md5');
$this->Auth->authenticate = array(
'Form' => array(
'fields' => array(
'username' => 'username',
),
),
);
}
}
Controller/UserController.php
class UsersController extends AppController {
public $uses = array('User');
public function beforeFilter() {
parent::beforeFilter();
}
public function isAuthorized($user){
return true;
}
public function login() {
$this->layout = 'login';
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Invalid username or password, try again','flash_error');
}
}
}
public function logout() {
$this->layout = 'login';
$this->Session->setFlash('Successfully logged out!','flash_success');
$this->redirect($this->Auth->logout());
}
}
View/Users/login.ctp
<?php
$this->set('title_for_layout', 'Login');
echo $this->Session->flash();
echo $this->Session->flash('auth','flash_info');
echo $this->Form->create('User', array(
'action' => 'login'
));
echo $this->Form->input('username',array(
'between' => '<br/>',
'before' => '<p>',
'after' => '</p>',
'class' => 'text',
'label' => 'Email:'
));
echo $this->Form->input('password',array(
'between' => '<br/>',
'before' => '<p>',
'after' => '</p>',
'class' => 'text',
'label' => 'Password:'
));
echo $this->Form->submit('Login', array(
'class' => 'submit',
'before' => '<p>',
'after' => '</p>'
));
echo $this->Form->end();
?>
You need to change the name of the field on your form from username to email. Just setting the label to "email" is not enough.
echo $this->Form->input('email',array(
'between' => '<br/>',
'before' => '<p>',
'after' => '</p>',
'class' => 'text',
'label' => 'Email:'
Try updating the components code in your appController to add the authenticate values to the Auth array like this:
public $components = array(
'Session',
'DebugKit.Toolbar',
'Auth' => array(
'allow' => array('login','logout'),
'loginAction' => array('controller' => 'users', 'action' => 'login'),
'loginRedirect' => array('controller' => 'dashboard', 'action' => 'index'),
'authorize' => 'Controller',
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email')
)
)
)
);