I want to use another table instead of users for authentication. I know I can change the table name in User.php as follows:
protected $table = 'WhatEver';
But this is not what I want. I want to change the name in the backend of the application so that a completely different model is used. How can I achieve that? What files do I need to change?
I found the solution. First create a new database table, which should have password and remember_token fields. In config/auth.php change the providers section as follows:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\NEW_MODEL_NAME::class,
],
After that, you need to alter App/Controller/Auth/RegisterController.php:
protected function validator(array $data) {
return Validator::make($data, [
'surname' => 'required|string|max:255',
'firstname' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:NEW_DB_TABLE_NAME',
'password' => 'required|string|min:6|confirmed',
]);
}
protected function create(array $data) {
return App\NEW_MODEL_NAME::create([
'surname' => $data['surname'],
'firstname' => $data['firstname'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
That's it.
Related
I am currently using this code in laravel to create a new account, but I want to retrieve the ID generated for this account
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
I want to do this, to also give permission to the police
$data['id']->syncRoles($data['roles']),
create method return the created elocuent model, and you can manage like:
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
if($user)
$user->syncRoles($data['roles']);
return $user;
I'm developing a API in YII2 with multiple databases. I want to choose the database in real time. The idea is to read one variable available in controler (API key) to identify the correct connection database in model.
For example in webapplication like a portal i have (it works):
in db default connection i have
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=dbcompany_0',
'username' => 'root',
'password' => 'XXXXXXXXXXXXXXXXXXXX',
'charset' => 'utf8',
],
In model I have
public function tableName()
{
$schema = '';
$user = User::find(Yii::app()->user->id);
$schema = "dbcompany_". $user->CompanyId;
return $schema . '.' . 'customer';
}
With this approach I just have a single db connection for all database companies.
How I can apply the same\similiar approach in API. I don't have sessions.
Any idea is well welcome.
Create a new component under db as:
'db1' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=dbcompany_0',
'username' => 'root',
'password' => 'XXXXXXXXXXXXXXXXXXXX',
'charset' => 'utf8',
],
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=dbcompany_0',
'username' => 'root',
'password' => 'XXXXXXXXXXXXXXXXXXXX',
'charset' => 'utf8',
],
And use it as:
Yii::$app->db1
Yii::$app->db2;
All requests are authenticate using a token and this is associated to the user. When the authentication is done YII Framework assigns the userid to \Yii::$app->user->identity->id. So from anywhere I can identify the company owner in model.
public static function tableName(){
$moreinfo= account\Userextra::findOne(\Yii::$app->user->identity->id);
$schema = \Yii::$app->params['table.prefix'] . $moreinfo->CompanyId;
return $schema . '.country';
}
What i'm doing wrong?
<?php
public function login() {
$user_name = time();
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'),
));
$user = array(
'email' => $user_name.'#test.com',
'password' => '123123',
);
$m = User::where('email' , '=', $user_name.'#test.com')->first();
dd([
'Auth::attempt($user)',
Auth::attempt($user),
'Auth::check()',
Auth::check(),
'Hash::check($m->password, \'123123\')',
Hash::check($m->password, '123123')
]);
}
Result:
array(6) {
[0]=>
string(20) "Auth::attempt($user)"
[1]=>
bool(false)
[2]=>
string(13) "Auth::check()"
[3]=>
bool(false)
[4]=>
string(38) "Hash::check($user->password, '123123')"
[5]=>
bool(false)
}
Not sure what information should I add.
app/config/auth.php
'driver' => 'eloquent',
'model' => 'User',
'table' => 'users',
app/config/app.php
'key' => 'DMmiPAxSYz4O2jG44S92OcdPZN7ZsGGs',
'cipher' => MCRYPT_RIJNDAEL_256,
models/User.php
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* Validation rules
*/
public static $rules = array(
'name' => 'required',
'email' => 'email|required|unique',
'password' => 'min:6',
);
/**
* Validation rules
*/
public static $messages = array(
'name.required' => 'The name field is required',
'email.email' => 'The email field must contain properly formatted email.',
'email.required' => 'The email field is required',
'password.required' => 'The password field is required',
'password.min:6' => 'The password must be minimum 6 characters long',
);
protected $table = 'users';
protected $hidden = array('password', 'remember_token');
protected $guarded = array('id');
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value);
}
}
}
Well here's some checks that you can do
Have you setup config/auth.php with driver, model and table?
Have you filled the fillable array of the User's model?
Have you change the key inside config/app.php ?
Also try to dd($m) in order to see what you got from that query.
I found what is wrong.
This part of code hash password for first time:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => Hash::make('123123'), // <---- first time
));
And this mutator in User model does hashing for second time before put password to database:
public function setPasswordAttribute($value) {
if ($value) {
$this->attributes['password'] = Hash::make($value); // <---- second time
}
}
So I just changed first block to this:
User::create(array(
'name' => $user_name,
'email' => $user_name.'#test.com',
'password' => '123123', // <---- no hashing here
));
I am using CakePHP 2.3, I want to save data as follows follows:
$insertUser = array(
'Name' => $Name,
'LastName' => $lastName,
'password' => $password,
'email' => $email,
'TimeStamp' => $presentTime,
'RefererUserId' => $refererId // set the referer user id
);
$this->SystemUser->saveAll($insertUser) // save record in table.
The above code is not working. I tried another method like:
$this->SystemUser->query("INSERT INTO system_users(Name,LastName,password,email,TimeStamp,RefererUserId) VALUES ('{$Name}','{$lastName}','{$password}','{$email}','{$presentTime}','{$refererId}')");
How can I now get the last inserted id? I used getLastInsertId() to get last inserted id, as below:
$lastid = $this->SystemUser->getLastInsertId();
But it does not seem to work.
Please try the below code. SystemUser is assumed as your model name.
$this->user_data = array(
'SystemUser' => array(
'Name' => $Name,
'LastName' => $lastName,
'password' => $password,
'email' => $email,
'TimeStamp' => $presentTime,
'RefererUserId' => $refererId // set the referer user id
));
if ($this->SystemUser->save($this->user_data)) {
$lastid = $this->SystemUser->getLastInsertId();
} else {
// do something
}
Your $insertUser should be the following
$insertUser['SystemUser'] = array(
'Name' => $Name,
'LastName' => $lastName,
'password' => $password,
'email' => $email,
'TimeStamp' => $presentTime,
'RefererUserId' => $refererId // set the referer user id
);
Then you should be save data as like
if($this->SystemUser->save($insertUser)) {
$lastid = $this->SystemUser->getLastInsertId();
} else {
debug($this->SystemUser->validationErrors); die();
}
This will probably give you the info you need (assuming it's not saving because of invalid data, of course):
debug($this->SystemUser->validationErrors); die();
That's it.
I would like to implement CakePHP 2 website over existing database with plain-text 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'),
'authenticate' => array(
'Form' => array(
'userModel' => 'User',
'fields' => array('username' => 'user_id', 'password' => 'user_password')
)
)
)
);
public function isAuthorized($user) {
return true;
}
function beforeFilter() {
$this->Auth->allow('home');
//$this->Auth->authenticate = $this->User;
parent::beforeFilter();
}
This is my UserController.
class UsersController extends AppController {
public $paginate = array(
'fields' => array('user_id', 'user_desc', 'user_password'),
'limit' => 25,
'order' => array(
'user_id' => 'asc'
)
);
function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash('Cannot Login');
}
}
}
}
This is my User model
class User extends AppModel {
public $name = 'User';
public $primaryKey = 'user_id';
public $belongsTo = 'Group';
}
According to those files above, when I pressed the Login button on login.ctp, I saw
select * from users where user_password = 'this_is_hashing_password'
on the sql dump section.
So, how to turn-off the automatic hashing algorithm, so the login() will compare the user input to the database stored password as plain-text???
I have tried lots of reading on the CakePHP book but I cannot find any, also using hashPasswords($data) technique which found from the internet is not working.
Please help.
Kongthap.
The best answer really is to batch-process your stored passwords so they are hashed, however there are cases where you may be adding a Cake app to an existing application that hashes passwords differently (say by not hashing them at all), so the question is valid even if the goal in this case is not.
Try these resources for modifying Cake's password hashing function, depending on your Cake version:
Cake 2.x
Cake 1.3
I got plain text password working in Cakephp 3, this should only be use for DEVELOPMENT purpose, you should never store password in plain text in production.
That being said, during development, plain text password allows me to focus on login instead of implementing a fully functional user encrypt/decrypt logic. Which is going to be replaced by an OAuth / SAML module anyway...
OK here comes the source code:
ROOT/src/Auth/PlainTextPasswordHasher.php
<?php
namespace App\Auth;
use Cake\Auth\AbstractPasswordHasher;
/**
* Plain text password for demo use, DO NOT PUSTH THIS TO PROD
*/
class PlainTextPasswordHasher extends AbstractPasswordHasher
{
public function hash($password)
{
return $password;
}
public function check($password, $hashedPassword)
{
return $password === $hashedPassword;
}
}
ROOT/src/Controller/PagesController.php
<?php
class PagesController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'username',
'password' => 'password',
],
'passwordHasher' => [
'className' => 'PlainText',
],
'userModel' => 'YourUsers',
]
],
'loginAction' => [
'controller' => 'Logins',
'action' => 'login'
]
]);
}
}
Source: This video https://www.youtube.com/watch?v=eASSNS1f3V4 and this section of the official doc: https://book.cakephp.org/3.0/en/controllers/components/authentication.html#creating-custom-password-hasher-classes