How to change default hash password in cakephp - cakephp

I have an existing website (functional) and now i need to upgrade my website by cakephp and also, import old DB to new DB.
Cakephp have default Algorithm for hash and password for that i need to change Algorithm .
My old website used this code for password:
$password_hash = hash('sha256', $password);
How can I set cakephp password hash auth like: hash('sha256', $password) until my website users can login into cakephp script?
please help...
cakephp ver: CakePHP(tm) v 0.2.9<br><br>
note: apologize For the weak English

I assume you are using CakePHP 3.x which uses the bcrypt hashing algorithm by default.
To use sha256 hasing you can create custom password hasher class.
namespace App\Auth;
use Cake\Auth\AbstractPasswordHasher;
class Sha256PasswordHasher extends AbstractPasswordHasher
{
public function hash($password)
{
return sha256($password);
}
public function check($password, $hashedPassword)
{
return sha256($password) === $hashedPassword;
}
}
and configure the AuthComponent to use your own password hasher:
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'passwordHasher' => [
'className' => 'Sha256',
]
]
]
]);
}
read more here https://book.cakephp.org/3.0/en/controllers/components/authentication.html#hashing-passwords

SHA3-512 is not supported in cakephp version 2.x, and in cakephp version 2.x we can use at max SHA-512.
You can do the same by making changes in app/Controller/AppController.php by adding below patch,
$this->Auth->authenticate = array(
'Form' => array(
'passwordHasher' => array(
'className' => 'Simple',
'hashType' => 'sha512' //passing sha512 as the hash type
)
)
);
If you are giving a option to change/reset password after updating your hash, you may use below patch to accept password with updated hash,
$var = Security::hash($password, 'sha512', true);
Here sha512 hash algorithm will be used, you can change it as per your hash requirement(sha1/sha256/md5/blowfish), if salt value i.e. third parameter is set to true application's salt value will be used.

Related

laravel 5.5 built in authentication database table reference location

I have a problem with using Laravel built in authentication feature. As a default Laravel authentication access users table to check/add username and password. I need to change it to student table. normally in a model protected $table=student code is used to mention which table to use.
Can anyone tell me where the protected $table= code or similar is found within the built in authentication feature?
Part 2
The code below is the code in my controller where I take the form data into $data and validating and returning it into my store function, but I get an error
Type error: Too few arguments to function App\Http\Controllers\StudentController::store(), 0 passed and exactly 1 expected"
protected function validator(array $data)
{
$data = Request::all();
return Validator::make($data, [
'fname' => 'required|string|max:255',
'lname' => 'required|string|max:255',
'district' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:student',
'password' => 'required|string|min:6|confirmed',
]);`
}
public function store(array $data)
{
return Student::create([
'fname' => $data['fname'],
'lname' => $data['lname'],
'district' => $data['district'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
Add it in the App\User.php
namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
protected $table = "users_old"; //your custom table
....
}
Add:
protected $table=student;
to User model at app/User.php
and
In app/Http/Controllers/Auth/RegisterController.php,
Change:
'email' => 'required|email|max:255|unique:users',
To:
'email' => 'required|email|max:255|unique:student',

Plugin route to a prefixed controller

I'm creating a plugin for my application (using CakePHP 2.6.0) that allows users to login into a user area using the same model as for the admin area, so I'm trying to get the same type of URI scheme as the admin area e.g. /admin/users/login but then for /special/users/login. I have the following route in my plugin's Config/routes.php and added the 'special' prefix to the 'Routing.prefixes' configuration:
Router::connect('/special/:controller/:action', array(
'special' => true,
'prefix' => 'special',
'plugin' => 'Special',
'controller' => ':controller',
'action' => ':action',
));
With above route and entering the following url /special/users/login it would make sense to me right now if Cake went for Plugin/Controller/SpecialUsersController.php (considering namespace conflicts with the main application's UsersController) but instead I get an error Error: Create the class UsersController.
Is there a built-in way for it to load a prefixed controller (without changing the url) based on the plugin? Or is there a better way to neatly extend my main application? Am I going about this the wrong way?
I could not find a built-in way for it to work as I wanted to so I changed the way URL strings were parsed using a custom route class in my app's Routing/Route/ folder:
App::uses('CakeRoute', 'Routing/Route');
/**
* Plugin route will make sure plugin routes get
* redirected to a prefixed controller.
*/
class PluginRoute extends CakeRoute {
/**
* Parses a string URL into an array.
*
* #param string $url The URL to parse
* #return bool False on failure
*/
public function parse($url) {
$params = parent::parse($url);
if($params && !empty($params['controller']) && !empty($params['plugin'])) {
$params['controller'] = $params['plugin'] . ucfirst($params['controller']);
}
return $params;
}
}
And then setting up my plugin routes as:
App::uses('PluginRoute', 'Routing/Route');
Router::connect('/special/:controller/:action', array(
'special' => true,
'prefix' => 'special',
'plugin' => 'Special',
'controller' => ':controller',
'action' => ':action',
), array(
'routeClass' => 'PluginRoute'
));
This resulted in /special/users/login creating the controller I wanted Plugin/Controller/SpecialUsersController.php, no side effects so far. Extending the main application's UsersController is a different story though.
Maybe someone else has use of this or knows a better solution?

CakePHP 2 separate login tables

I have a Cake website and it needs to have two separate logins, each one will have their own login form and see different pages, it would be nice to have two different tables because there are no similarities between the two types of people.
Each login form will only be used by certain people and they will never login to the other form, and vice versa.
Also, the two login tables have a relationship between them, which requires 2 tables?
Is this possible?
First, add a couple of empty custom authenticate objects. We'll reuse the same logic that FormAuthenticate uses (that is, uses POST data to check the database for a user), but simply change the model within the object settings (later).
app/Controller/Component/Auth/ModelOneAuthenticate.php
<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');
class ModelOneAuthenticate extends FormAuthenticate {
}
app/Controller/Component/Auth/ModelTwoAuthenticate.php
<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');
class ModelTwoAuthenticate extends FormAuthenticate {
}
Then tell your app to use these objects to authenticate, and tell it what model to use. You can also customize the fields here. In your AppController:
public $components = array(
'Auth' => array(
'authenticate' => array(
'ModelOne' => array(
'userModel' => 'ModelOne',
'fields' => array(
'username' => 'my_custom_username_field',
'password' => 'some_password_field'
)
),
'ModelTwo' => array(
'userModel' => 'ModelTwo'
)
)
)
);
The first authentication object would check the model_ones table for a username in my_custom_username_field and password in some_password_field, while the second one would check model_twos using the standard username and password fields.
The simplest way to do this is to just set a different session key for each login type:
if ($loginTypeOne) {
$this->Auth->authenticate = array(
'Form'=> array(
'userModel'=> 'TypeOne',
)
);
AuthComponent::$sessionKey = 'Auth.TypeOne';
} else {
$this->Auth->authenticate = array(
'Form'=> array(
'userModel'=> 'TypeTwo',
)
);
AuthComponent::$sessionKey = 'Auth.TypeTwo';
}
When they have to login there is a similarity: Both will require it to enter credentials, usually an username/email and password. So a users table and a foo_profiles table and a bar_profiles table depending on the user type should work also.
If you really want to go with two total different tables and the MVC stack for them, then simply use two different controllers FooUsers and BarUsers and inside of each create a customized login method.
I have done this previously by writing custom Authentication components that extend from BaseAuthenticate. As long as they implement the authenticate() method then you'll be able to do whatever you want to each of the different types of user.
In your AppController you need to register the different components by doing something like
public $components = array(
"Session",
"Auth" => array(
'authenticate' => array("UserType1", "UserType2"),
)
);
Check out the cookbook for the rest of it.
You can have a look on this.
Define Model for both login member and then define table which you want to use for the user.
set variable in model.
class SearchedCategory extends AppModel {
var $name = 'SearchedCategory';
Var useTable = 'give your table name here.';
var $primaryKey = 'id';
}

How do I create a guest account without actually placing it in the db in CakePHP?

So I have a pretty typical user model, nothing special about it. I'd like to be able to use this model as a guest user when no other user is logged in.
Is there a way to create a guest account, or some sort of default when no account is set, in CakePHP so that Auth contains that?
So, for example, the id would be set as 0, username would be set to guest, etc.
Thank you,
James
You could override the find method at your User model, so that when Auth calls it (internally), you can intercept that and return whatever your want instead. Something like this (on your User model):
public function find($conditions, $fields, $order=null, $recursive=false) {
$user = parent::find($conditions, $fields, $order, $recursive);
if(empty($user)) {
// No "real" user found, let's create "guest"
$user = array(
'User' => array(
'id' => 0,
'username' => 'guest'
// add other fields as needed
)
);
}
return $user;
}
Just add it to the session.
$this->Session->write(AuthComponent::$sessionKey, array(
'User' => array(
'id' => 0,
'username' => 'guest'
)
));
In AppController :
public function beforeFilter() {
if(!$this->Auth->loggedIn()){
$this->loadModel('User');
$user = $this->User->findById(0); //Guest user id
$this->Auth->login($user['User']);
}
}
This works fine for me with CakePHP 2.2.
It allows permission configuration including guest's permission via a web interface : http://www.alaxos.net/blaxos/pages/view/plugin_acl_2.0

CakePHP 2.0.5 Auth and User Model Recursive issue

In Cake 2.0.5 when logging in using the Auth component, it would seem Cake is retrieving all related models; and with many associations, logging in takes a long time.
This problem was first identified here in this ticket but the "solution" given doesn't mean a lot, and I can't find anything else in the documentation.
Using the FormAuthenticate class in 2.0 you can subclass and add
whatever recursive level you feel is appropriate fairly easily.
Has anyone experienced this, and have a fix?
Below - sample code:
Standard login method:
public function login() {
$this->User->recursive = -1; // does nothing
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Invalid username or password.');
}
}
And the query cake is producing for my app:
SELECT `User`.`id`, `User`.`username`, `User`.`password`, `User`.`role`, `User`.`created`, `User`.`modified`, `Band`.`id`, `Band`.`name`, `Band`.`genre`, `Band`.`location`, `Band`.`influences`, `Band`.`founded`, `Band`.`bio`, `Band`.`created`, `Band`.`modified`, `Band`.`status`, `Band`.`website`, `Band`.`email`, `Band`.`contact_number`, `Band`.`user_id`, `Member`.`id`, `Member`.`user_id`, `Member`.`first_name`, `Member`.`last_name`, `Member`.`display_name`, `Member`.`dob`, `Member`.`gender`, `Member`.`bio`, `Member`.`influences`, `Member`.`band_id` FROM `users` AS `User` LEFT JOIN `bands` AS `Band` ON (`Band`.`user_id` = `User`.`id`) LEFT JOIN `members` AS `Member` ON (`Member`.`user_id` = `User`.`id`) WHERE `User`.`username` = 'admin' AND `User`.`password` = 'dcec839a9258631138974cbccd81219f1d5dfcfa' LIMIT 1
As you can see it's retrieving every field, and joining every model. My app only has 2 additional associations, but you can see how this might be an issue with very complex apps.
When really, it should just be the users table. Setting recursive appears to do absolutely nothing.
You can use recursive option for Auth component.
public $components = array(
'Auth' => array(
'authenticate' => array(
'Form' => array('recursive' => -1)
)
)
or in beforeFilter method:
$this->Auth->authenticate = array('Form' => array('recursive' => -1));
What Mark is suggesting is to extend the FormAuthenticate class, or essentially override it.
Create a new file app/Controller/Component/Auth/ExtendedFormAuthenticate.php
This is the basic structure of the code - I've left in the important bit where the recursive level is set in the _findUser method:
App::uses('FormAuthenticate', 'Controller/Component/Auth');
class ExtendedFormAuthenticate extends FormAuthenticate
{
public function authenicate(CakeRequest $request, CakeResponse $response) {
// foo
}
protected function _findUser($username, $password)
{
// bar
$result = ClassRegistry::init($userModel)->find('first', array(
'conditions' => $conditions,
'recursive' => -1
));
// fooBar
}
}
I've created a Gist with the whole lot in: https://gist.github.com/1565672
Oh, almost forgot, you'll need to setup the AuthComponent to use the extended class.
public $components = array(
'Auth'=> array(
'authenticate' => array(
'ExtendedForm'
)
),
);
What about using Containable and override find at model?
Modifying Containable fields required in beforeFind callback?

Resources