I am developing an application using cakephp 2.3.9 .It got a users table to save user credentials .How do i use a different field in User table other than password field to save password.
You can try this:
public $components = array(
'Auth' => array(
'loginAction' => array(
......
),
'authError' => '...',
'authenticate' => array(
'Form' => array(
'fields' =>
array(
'password' => 'YOUR_CUSTOM_FIELD' // set custom field
// as password field
)
)
)
)
);
in AppController.php.
And in your Form set type="password" to that field. e.g.
$this->Form->input('YOUR_CUSTOM_FIELD', array('type' => 'password'));
Referencing comment, to encrypt the password field you need to do manual approach in your controller or model. e.g. in controller you can do like:
$this->request->data['User']['YOUR_CUSTOM_FIELD'] = AuthComponent::password( $this->request->data['User']['YOUR_CUSTOM_FIELD']);
Also you can do model beforeSave() function also by proper checking in case of add/edit action.
Ref:
CakePHP Auth Password Hash
For detail about CakePHP Auth
Related
I am building the application using cakephp.
I have choosed the cakephp2.3.
User would be authenticated using either 'email' OR 'username'.
I found one option with Auth component "scope", but with this we can set static conditions.
LIKE: if user is active,, is_active => 1
But I want that while authenticating auth component should check either 'email' or 'username' field and other is password.
Is there any way?
This needs some code. You can easily find it through Users/CakeDC plugin found here
This plugin Uses the auth component below for login with multiple columns.
https://github.com/CakeDC/users/blob/master/Controller/Component/Auth/MultiColumnAuthenticate.php
It also includes an example of how to use. If you don't want the whole plugin you can just copy the MultiColumnAuthenticate.php to the folder app/Controllers/Components/Auth/.
if you copy only the file then in beforeFilter method inside your AppController you must write:
class AppController extends Controller {
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->authenticate = array(
'MultiColumn' => array( //With no plugin
'fields' => array(
'username' => 'username',
'password' => 'password'
),
'columns' => array('username', 'email'),
)
);
}
}
according to cakephp documentation.
FormAuthenticate allows you to authenticate users based on form POST data. Usually this is a login form that users enter information into
By default AuthComponent uses FormAuthenticate
you can try this:
// Pass settings in $components array
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'email', 'password' => 'password')
)
)
)
);
CakePHP v.2.4...
I'm following this documentation trying to set up the Auth component to use my custom password hashing class:
App::uses('PHPassPasswordHasher', 'Controller/Component/Auth');
class AppController extends Controller {
// auth needed stuff
public $components = array(
'Session',
'Cookie',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array('username'=>'email', 'password'=>'password'),
'passwordHasher' => 'PHPass'
)
),
Inside my UsersController::login() I debug the return from $this->Auth->login(); and it always returns false, even when I submit the correct email / password.
(NOTE: It looks strange to me that the login() takes no parameters, but the docs seem to imply that it looks into the the request data automatically. And this would make sense if my configurations aren't correctly causing it to check the User.email field instead username.)
The post data from the submitted login form looks like this:
array(
'User' => array(
'password' => '*****',
'email' => 'whatever#example.com'
)
)
What am I missing?
Update2
I'm starting to suspect that the default hashing algorithm is getting used instead of my custom class. I tried to match the examples in the docs but they're quite vague on how to do this.
Here's the contents of app/Controller/Component/Auth/PHPassPasswordHasher.php
<?php
App::import('Vendor', 'PHPass/class-phpass'); //<--this exists and defines PasswordHash class
class PHPassPasswordHasher extends AbstractPasswordHasher {
public function hash($password) {
$hasher = new new PasswordHash( 8, true );
return $hasher->HashPassword($password);
}
public function check($password, $hashedPassword) {
debug('PHPassHasher'); die('Using custom hasher'); //<--THIS NEVER HAPPENS!
$hasher = new new PasswordHash( 8, true );
return $hasher->CheckPassword($password, $hashedPassword);
}
}
AHA! The debug() never appears... so I'm pretty sure the problem is with my custom hasher configuration(s).
Update3
Additional clue: I experimented by setting various default hashing algorithms (Ex: "Simple", "Blowfish") and creating users. The hashes which show up in the DB are all the same which tells me that my config settings are getting ignored completely.
Update4
I debugged $this->settings inside the constructor of /lib/Cake/Controller/Component/Auth/BaseAuthenticate.php and my custom hasher settings are in there:
array(
'fields' => array(
'password' => 'password',
'username' => 'email'
),
'userModel' => 'User',
'scope' => array(),
'recursive' => (int) 0,
'contain' => null,
'passwordHasher' => 'PHPass'
)
You need to rename your password hasher class to have the suffix "PasswordHasher", and only provide the non-suffixed name in the 'className' argument.
eg:
<?php
App::import('Vendor', 'PHPass/class-phpass'); //<--this exists and defines PasswordHash class
class PHPassHasherPasswordHasher extends AbstractPasswordHasher {
// functions
}
The example from the docs sets the classname to 'Simple', which then loads 'SimplePasswordHasher'.
You might find that having a name of PHPassHasherPasswordHasher is a bit silly, it's up to you what you want to call it. Perhaps PHPassPasswordHasher might be a bit more appropriate (and then use the classname argument 'PHPass').
EDIT: It seems as if Cake has issues when multiple capital letters are used one after the other (eg. PHPass), so the right way to do it is to change the password hasher class to the following:
<?php
App::import('Vendor', 'PHPass/class-phpass'); //<--this exists and defines PasswordHash class
class PhpassPasswordHasher extends AbstractPasswordHasher {
// functions
}
... and make sure the filename matches the classname: PhpassPasswordHasher.php.
Thanks to SDP for the discussion, I learnt something today!
According to the docs:
To configure different fields for user in $components array:
// Pass settings in $components array
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array(
'fields' => array(
'username' => 'email',
'password' => 'password'
)
)
)
)
);
Source
I finally got this working. We were on the right track by renaming the file/class to comply with Cake conventions. I had to go one step further and change the capitalization as well:
PHPassPasswordHasher.php --> PhpassPasswordHasher.php
class PHPassPasswordHasher... --> class PhpassPasswordHasher...
Phew!
ps: Many many thanks to #Ben Hitchcock for support on this.
I have a mongo db structure for users with "username" and "password". I am trying to use the Auth in cakephp login but it seems like its not working for me. I tried removing the $this->data but still it did not work.
My password is hashed using Security::hash($this->data['User']['password'])
if(!empty($this->data))
{
if($this->Auth->login($this->data))
{
echo "yes";
}
else{
echo "no";
}
}
In my app controller I have this:
public $components = array('DebugKit.Toolbar', 'Session', 'Auth' => array(
'loginAction' => array(
'controller' => 'pages',
'action' => 'home'
),
'authenticate' => array(
'Form' => array(
'fields' => array('username' => 'username', 'password' => 'password')
)
)
));
Here is the result when I debug the login method:
array(
'User' => array(
'password' => '*****',
'username' => 'test#test.com',
'remember' => '0',
'auto_login' => '0'
)
)
I don't know why I cannot use Auth with mongodb. Thanks for the help in advance.
EDIT:
When i tried and take away the layout, it shows me a query at the bottom of the page saying:
db.users.find( {"username":"test#test.com","password":"2fdf49ffc396453960802df8fc2417655d1e8fca"}, [] ).sort( [] ).limit( 1 ).skip( 0 )
The hashed value of the password that I inputted from the form is different from the hash value that is being queried. The hashed value should be "a2374c309ab7823dcd9b4e21dae7511f7a9c7ec5". Why is it that cakephp is converting the password into another hash value?
There are two ways of using $this->Auth->login(). The CakePHP API documentation explains it:
If a $user is provided that data will be stored as the logged in user. If $user is empty or not specified, the request will be used to identify a user.
The manual also mentions:
In 2.0 $this->Auth->login($this->request->data) will log the user in with whatever data is posted ...
So for the login method of the users controller you shouldn't pass anything:
if($this->Auth->login()) {
// user is now logged in
}
Should you need to manually login a user you can pass the user data as an array:
if($this->Auth->login($this->request->data['User'])) {
// user is now logged in
}
Where $this->request->data['User'] is something like:
array(
'id' => 1,
'username' => 'admin',
'password' => '1234',
);
Note: In both cases you don't need to hash the password as it is done automatically.
I was able to find out the answer. Its because cakephp is automatically hashing the password when searching in the database.
The problem that I had was when I was saving the users' password, I am was using
Security::hash($this->data['User']['password'])
I should have used this one instead:
AuthComponent::password($this->data['User']['password'])
Thank you for all the help especially to #xgalvin
with cake 1.3 for autologin facebook users i get the user info from database:
$userInfo = $this->User->find('first', array(
'fields' =>array('User.username','User.password'),
'conditions' => array(
'source_id' => $fb_user_id,
'source' => "facebook",
)
));
password comming from this select is hashed.
and i use this method for authentication
$this->Auth->login($userInfo);
but now with cake 2
var_dump($this->Auth->login($userInfo));
always return false;
i 'm not sure but i think that now the login() method need a clear password??
any solution? and excuse my English
Try $this->Auth->login($userInfo['User']), to login user in cakephp 2.0 you should use array with users data, without mention model
If its will not help then check if your Auth component configuration is right...
I use
$this->Auth->authenticate = array(
'all' => array(
'userModel' => 'User',
),
'Form'
);
$this->Auth->loginAction = {url};
$this->Auth->logoutAction = {url}
I want to test login function if it works propperly and only lets valid and active users in.
My user fixture contains:
array(
'password' => '*emptyPasswordHash*', // empty password
'username' => 'Lorem',
'balance' => 0,
'currency' => 'USD',
'id' => 1,
'user_group_id' => 3, //Customer
'active' => 1,
'hash' => 'LoremHash'
),
My test function looks like this:
function testLogin() {
//test valid login
$result = $this->testAction('/users/login', array(
'data' => array(
'User' => array(
'username' => 'Lorem',
'pass' => '',
'remember' => true
)),
'method' => 'post',
'return' => 'view'
));
debug($result);
}
The login form has 3 inputs: username, password and remember
I have set $this->Auth->autoRedirect = false; in the UsersController::beforeFilter and I am doing some cookie setting stuff
when I debug($this->data); in UsersController::login() it shows the exact same data when testing and when logging normaly. But while testing the login fails and I get $this->Auth->loginError message instead of a login.
How do I test login action propperly?
if you use cakes Auth component and dont hack it up you dont need to...
https://github.com/cakephp/cakephp/blob/master/cake/tests/cases/libs/controller/components/auth.test.php#L545
and if you really want to, look at how the pro's do it :)
Did you also set your custom function, like described in The CakePHP manual:
Normally, the AuthComponent will
attempt to verify that the login
credentials you've entered are
accurate by comparing them to what's
been stored in your user model.
However, there are times where you
might want to do some additional work
in determining proper credentials. By
setting this variable to one of
several different values, you can do
different things.