I just need a bit of help with identifying the email of the user which is also the username in the database, I used the 'isUnique' in the model but for some reason it is not giving an error message and it still registers the user please can someone give me a bit of help here is the code...
MODEL
App::uses('AuthComponent','Controller/Component');
class User extends AppModel {
public $validate = array(
'email' => 'email',
'email' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Please enter a valid email address for username',
'unique' => array(
'rule' => 'isUnique',
'message' => 'Please enter another email, this one is already taken'
)
)
),
'password' => array(
'required'=> array(
'rule' => array('notEmpty'),
'message' => 'Please enter a valid password',
'rule' => array('minLength','8'),
'message' => 'Please enter minimum 8 characters'
)
)
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
}
**CONTROLLER**
<?php
class usersController extends AppController
{
public function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('add');
}
var $name = 'Users';
public function add()
{
if (!empty($this ->data))
{
$this->User->create();
if ($this->User->save($this->data))
{
$this->Session->setFlash('Thank you for registering');
$this->redirect(array('action'=>'index'));
}
else
{
// Make the password fields blank
unset($this->data['User']['password']);
unset($this->data['User']['confirm_password']);
$this->Session->setFlash('An error occurred, try again!');
}
}
}
function index()
{
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirectUrl());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
public function logout() {
return $this->redirect($this->Auth->logout());
}
}
VIEW
<h2>End a problem registration</h2>
<p>Please fill out details to register</p>
<?php
echo $this->Form->Create('User',array('action' => 'add'));
echo $this->Form->input('title');
echo $this->Form->input('name');
echo $this->Form->input('surname');
echo $this->Form->input('email');
echo $this->Form->input('password');
echo $this->Form->input('password');
echo $this->Form->end('Register');
Your array declarations for your validation rules are wrong.
They have the wrong "level", thus making them invalid.
E.g. email key is used twice.
Please correct them according to the documentation - and using correct 1 tab indentation.
This will make them both correct and readable and easily prevents the mistake you made above.
Related
i am new in cakePHP framework with version 2.0 my problem is when i save the data or insert the new record the field is empty or no data to be save how can i fix this. .
My Model
class Post extends AppModel{
public $name = 'posts';
}
My Controller
public function add(){
if($this->request->is('post')){
$this->Post->create();
if($this->Post->save($this->request->data)){
$this->Session->setFlash('The posts was saved');
$this->redirect('index');
}
}
}
My View
echo $this->Form->create('Create Posts');
echo $this->Form->input('title');
echo $this->Form->input('body');
echo $this->Form->end('Save Posts');
You need to put the validation rules in the Post model, Then you can check validate data or not in the controller action before save into model. See the following Model and controller
In Model
class Post extends AppModel{
public $name = 'posts';
public $validate = array(
'title' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'This is can'\t blank'
),
),
'body' => array(
'alphaNumeric' => array(
'rule' => 'alphaNumeric',
'required' => true,
'message' => 'This is can'\t blank'
),
),
);
}
In Controller
public function add(){
if($this->request->is('post')){
$this->Post->create();
$this->Post->set($this->request->data);
if ($this->Post->validates()) {
// it validated logic
if($this->Post->save($this->request->data)){
$this->Session->setFlash('The posts was saved');
$this->redirect('index');
}
} else {
// didn't validate logic
$errors = $this->Post->validationErrors;
}
}
}
In version 2.2.1 I could validate a form using rules and custom messages like below. But somehow the password rule isn't working as of version 2.3. Any help what I might be doing wrong here?
Model:
class User extends AppModel {
public $validate = array(
'password' => array(
'rule' => array ('between', 5, 10 ),
'message' => 'Password must between 5 and 10 characters long'
)
);
public function beforeSave($options = array()) {
$this->data['User']['password'] = Security::hash($this->data['User']['password'], 'sha1', true);
return true;
}
}
View:
<?php
echo $this->Form->create();
echo $this->Form->input('firstname', array('label' => 'First name'));
echo $this->Form->input('lastname', array('label' => 'Last name'));
echo $this->Form->input('adminrole', array('type' => 'checkbox', 'label' => 'Is admin?<br /><br />'));
echo $this->Form->input('email', array('label' => 'E-mail address'));
echo $this->Form->input('password', array('label' => 'Password'));
echo $this->Form->input('picturethumb', array('type' => 'file', 'label' => 'Profile picture'));
echo $this->Form->end('Save');
?>
Please bare in mind that this exact same code validates correctly in 2.2.1
Controller:
class UsersController extends AppController {
public function index() {
$users = $this->User->find('all');
$this->set('users', $users);
}
public function add() {
if ($this->request->is('post')) {
$this->User->save($this->request->data);
$this->redirect('/users');
}
}
}
Try this-
public function add() {
if ($this->request->is('post')) {
$this->User->create();
if($this->User->save($this->request->data)){
$this->redirect('/users');
}else{
$this->Session->setFlash('Opps... Something is wrong');
}
}
}
I don't work with cake sometime, but I remember had this problem before. The problem is, the cakephp will create a hash of password, so when Model get password is already big. What I did in time was make another validate, like password_tmp and use it like field and create the hash by myself in controller for the real field password.
I created a User with the hash provided by the Cake .. But when I go to log in, says 'Invalid username or password'. But it's all right.
The $this->Auth->login(); always returns false...
Crontroller
class MastersController extends AppController{
public function login(){
if ($this->request->is('post')) {
debug($this->Auth->login());
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
}
else {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
}
public function logout(){
$this->redirect($this->Auth->logout());
}}
AppController
class AppController extends Controller {
public $components = array('Session', 'Cookie', 'Auth');
function beforeFilter() {
$this->loadModel('Master');
$this->Auth->userModel = 'Master';
$this->Auth->allow('*');
// Action da tela de login
$this->Auth->loginAction = array(
'masters' => false,
'controller' => 'masters',
'action' => 'login'
);
// Action da tela após o login (com sucesso)
$this->Auth->loginRedirect = array(
'masters' => true,
'controller' => 'masters',
'action' => 'index'
);
// Action para redirecionamento após o logout
$this->Auth->logoutRedirect = array(
'masters' => false,
'controller' => 'pages',
'action' => 'login'
);
$this->Auth->authorize = array('controller');
if (!isset($this->params['masters']) || !$this->params['masters'])
$this->Auth->allow('*','login');
$this->Auth->loginError = __('Usuário e/ou senha incorreto(s)', true);
$this->Auth->authError = __('Você precisa fazer login para acessar esta página', true);
}
public function isAuthorized($masters){
return TRUE;
}}
VIEW login.ctp
echo 'Formulário de login';
echo $this->Session->flash('auth');
echo $this->Session->flash();
echo $this->Form->create('Master', array('controller'=>'masters','action'=>'login'));
echo $this->Form->input('username');
echo $this->Form->input('password');
echo $this->Form->end('Entrar');
Model
class Master extends AppModel{
public $name = 'Master';
public $validate = array(
'username' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Usuario requerido.'
)
),
'password' => array(
'required' => array(
'rule' => array('notEmpty'),
'message' => 'Senha requerida.'
)
)
);
public function beforeSave($options = array()) {
if (isset($this->data[$this->alias]['password'])) {
$this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
}
return true;
}
I don't know why it is giving this error .. This all seems ok!
I changed one letter of Security.salt, as he asked ..
Help me :)
I need it for work
debug($this->Auth->login());
if ($this->Auth->login()) {}
is a bad idea.
the first will log you in,
the second call will then - of course - return false (since you are already logged in).
If you really need to test this way, halt the code:
debug($this->Auth->login()); die();
I had the same problem and what fixed it for me was changing $this->alias to User, so beforeSave() now looks like
public function beforeSave($options = array()) {
if (isset($this->data['User']['password'])) {
$this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
}
return true;
}
In my present system I need to login using username or email and password.
can anybody knows how to achieve this ?
My Form:
<?php echo $this->Form->create('User', array('action' => 'login'));
echo $this->Form->input('username', array('class' => 'TextField js-user-mode'));
echo $this->Form->input('password', array('class' => 'TextField'));
?>
MY AppController:
public $components = array(
'Email'=>array(),
'Auth' => array(
'loginAction' => array(
'admin' => false,
'controller' => 'users',
'action' => 'login'
),
'authError' => 'Your session has ended due to inactivity. Please login to continue.',
'authenticate' => array(
'Form' => array(
'fields' => array('username' => array('username','email')),
),
'all' => array(
'userModel' => 'User',
'scope' => array('User.status' =>array('active'))
)
)
)
);
Let me know what else i need to do..??
I'm not sure what the etiquette is on posting answers to old questions but here's what I did for this.
In my login function
$username = $this->data['User']['username'];
$password = $this->request->data['User']['password'];
$user = $this->User->findByUsername($username);
if (empty($user)) {
$user = $this->User->findByEmail($username);
if (empty($user)) {
$this->Session->setFlash(__('Incorrect Email/Username or Password'));
return;
}
$this->request->data['User']['username'] = $user['User']['username'];
}
I found following code from this url. I think this is the best in sense of simplicity. Use following code on your login action:
public function login() {
if($this->request->is('post')&&!empty($this->request->data)) {
App::Import('Utility', 'Validation');
if( isset($this->data['User']['username']) && Validation::email($this->request->data['User']['username'])) {
$this->request->data['User']['email'] = $this->request->data['User']['username'];
$this->Auth->authenticate['Form'] = array('fields' => array('username' => 'email'));
}
if($this->Auth->login()) {
/* login successful */
$this->redirect($this->Auth->redirect());
} else {
/* login unsuccessful */
}
}
}
And also use following code for login.ctp :
<?php
echo $this->form->create('User');
echo $this->form->input('username');
echo $this->form->input('password');
echo $this->form->end('Submit');
?>
Simply we can do this before your Auth login action:
$emailUsername = #$this->request->data['User']['email'];
if (!filter_var($emailUsername, FILTER_VALIDATE_EMAIL)) {
$emailFromUsername = $this->User->find('first', array('conditions' => array('User.username' => $emailUsername), 'recursive' => -1, 'fields' => array('email')));
//pr($emailFromUsername );
if (!empty($emailFromUsername)) {
$emailFromUsernameDB = $emailFromUsername['User']['email'];
} else {
$emailFromUsername = '';
}
$this->request->data['User']['email'] = $emailFromUsername;
}
Assuming you have username and email both fields in your users table
In your AppController.php
public function beforeFilter() {
if ($this->request->is('post') && $this->action == 'login') {
$username = $this->request->data['User']['username'];
if (filter_var($username, FILTER_VALIDATE_EMAIL)) {
$this->Auth->authenticate['Form']['fields']['username'] = 'email';
$this->request->data['User']['email'] = $username;
unset($this->request->data['User']['username']);
}
}
}
This code will work for CakePHP 2.x, not tested on version 3.x, you should have email field in your user's table.
You can leverage the MultipleColumn Auth adapter:
https://github.com/ceeram/Authenticate/blob/master/Controller/Component/Auth/MultiColumnAuthenticate.php
Update:
New version # https://github.com/dereuromark/cakephp-tools/blob/master/src/Auth/MultiColumnAuthenticate.php
I found this solution useful.
I have created two classes that extend FormAuthenticate:
app/Controller/Component/Auth/ClassNameAuthenticate.php and
<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');
class ClassNameAuthenticate extends FormAuthenticate {
}
app/Controller/Component/Auth/ClassNameEmailAuthenticate.php
<?php
App::uses('FormAuthenticate', 'Controller/Component/Auth');
class ClassNameEmailAuthenticate extends FormAuthenticate {
}
then in my Controller added Auth Component to $components
public $components = array(
'Session',
'Auth' => array(
'authenticate' => array(
'ClassName' =>array(
'userModel'=>'ClassName',
'fields' => array(
'username' => 'username',
),
'scope' => array('ClassName.active' => 1)
),
'ClassNameEmail' =>array(
'userModel'=>'ClassName',
'fields' => array(
'username' => 'email',
),
'scope' => array('ClassName.active' => 1)
)
)
),
);
login view: login.ctp
<div class="form">
<?php echo $this->Form->create('ClassName'); ?>
<fieldset>
<legend><?php echo __('Login'); ?></legend>
<?php
echo $this->Form->input('username');
echo $this->Form->input('password');
?>
</fieldset>
<?php echo $this->Form->end(array('label'=>__('Login'))); ?>
</div>
and login() action:
public function login(){
if ($this->Auth->loggedIn()) {
return $this->redirect($this->Auth->redirect());
}
if ($this->request->is('post')) {
//Need to duplicate field email for ClassNameEmail Auth
$this->request->data['ClassName']['email'] = $this->request->data['ClassName']['username'];
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
}
$this->Session->setFlash(__('Invalid username/email or password, try again'));
}
}
I hope someone will find this useful.
this is my solution to solve that problem
public function login(){
if($this->request->is('post')){
$this->User->set($this->request->data);
if($this->User->validates()){
if(Validation::email($this->data['User']['username'])){
$this->Auth->authenticate['Form'] = array_merge($this->Auth->authenticate['Form'],array('fields'=>array('username'=>'email')));
$this->request->data['User']['email'] = $this->request->data['User']['username'];
unset($this->request->data['User']['username']);
}
if($this->Auth->login()){
$this->User->id = $this->Auth->user('id');
$this->User->saveField('last_login',time());
if($this->data['User']['remember']){
unset($this->request->data['User']['remember']);
$this->request->data['User']['password'] = Security::hash($this->request->data['User']['password'],'blowfish');
$this->Cookie->write('rememberMe',$this->request->data['User'],true,'2 days');
}
$this->redirect($this->Auth->loginRedirect);
}
$this->Session->setFlash('Invalid Username or Password entered, please try again.','default',array('class'=>'alert alert-warning'),'warning');
}
}
$this->set('title','Login Page');
}
I followed tutorial on CakephpTV to make registration by AuthComponent. Yesterday everything worked good, but today it isn't.
When I'm trying to add new account it says that passwords do not match, and in password field there is hashed password and in password confirmation there is normal (not hashed) password.
My UserController class:
class UsersController extends AppController
{
function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow('new_user');
if($this->action == 'add' || $this->action == 'edit') {
$this->Auth->authenticate = $this->User;
}
}
function new_user()
{
if (!empty($this->data)) {
if ($this->User->save($this->data)) {
$this->Session->setFlash('Rejestracja zakończona pomyślnie');
$this->redirect(array('action' => 'index'));
}
}
}
function login() {
}
function logout() {
$this->redirect($this->Auth->logout());
}
}
My User model:
class User extends AppModel {
var $name = 'User';
var $validate = array (
'email' => array(
'Please supply a valid email address.' => array(
'rule' => 'email',
'message' => 'Please supply a valid email address.'
),
'Already exists' => array(
'rule' => 'isUnique',
'message' => 'Must be unique'
)
),
'password' => array (
'aThis field must have between 6 and 40 alphanumeric characters.' => array(
'rule' => '/^[^\'"]{6,40}$/i',
'message' => 'aThis field must have between 6 and 40 alphanumeric characters.'
),
'Do not match' => array(
'rule' => 'matchPasswords',
'message' => 'Do not match'
)
)
);
function matchPasswords($data) {
if($data['password'] == $this->data['User']['password_confirmation']) {
return TRUE;
}
$this->invalidate('password_confirmation', 'DO not match');
return FALSE;
}
function hashPasswords($data) {
if(isset($this->data['User']['password'])) {
$this->data['User']['password'] = Security::hash($this->data['User']['password'], NULL, TRUE);
return $data;
}
return $data;
}
function beforeSave() {
$this->hashPasswords(NULL, TRUE);
$this->data['User']['registration_date'] = date("Y-m-d H:i:s");
return TRUE;
}
}
My new_user.ctp:
echo $this->Form->create('User', array('action' => 'new_user'));
echo $this->Form->input('email');
echo $this->Form->input('password');
echo $this->Form->input('password_confirmation',array('type' => 'password'));
echo $this->Form->end('Zarejestruj');
My AppController class:
class AppController extends Controller {
var $components = array('Auth','Session');
function beforeFilter() {
$this->Auth->fields = array('username' => 'email', 'password' => 'password');
$this->Auth->allow('index','view','display','new_user');
$this->Auth->authError = 'Zaloguj się aby zobaczyć tą stronę.';
$this->Auth->loginError = 'Wprowadzono niepoprawne dane.';
$this->Auth->loginRedirect = array('controller'=>'pages','action'=>'home');
$this->Auth->loginRedirect = array('controller'=>'pages','action'=>'home');
}
}
CakePHP automatically hashes fields named password in a User model. This is why you get an already hashed password back when the form fails. You might want to check if the hash you get back is the same hash as you'd expect to get back.
Apart from that, in your function matchPasswords your checking on $this->data['password'] whereas I think that should be $this->data['User']['password'].