Good Morning,
I have got issue with login into my web application.
When I'm registering on my app there is no error (In my opinion):
//Register
public function register() {
$user = $this->Users->newEntity();
if($this->request->is('post')) {
$this->request->data('status', '0');
$this->request->data('role', '0');
$user = $this->Users->patchEntity($user, $this->request->data);
if($this->Users->save($user)) {
$this->Flash->success('You are registered and can login');
return $this->redirect(['action' => 'login']);
} else {
$this->Flash->error('You are not registered');
}
}
$this->set(compact('user'));
$this->set('_serialize', ['user']);
}
When the user is registered I cant login (And I dont know why), but if I will login on other user and I'm changing the password for old user -> old user can log in.
I dont know where is the cause of issue.
Login:
//Login
public function login() {
if($this->request->is('post')) {
$user = $this->Auth->identify();
//dump($user);
//die();
if($user) {
if($user['status'] == '1') {
$this->Auth->setUser($user);
return $this->redirect(['controller' => 'tasks']);
}elseif($user['status'] == '0') {
$this->Flash->error('You are not authorized to Log In. Please contact with Admin of Application');
}
} else {
//Bad Login
$this->Flash->error('Incorrect Login or Password');
}
}
}
The interesting thing is that when I'm logging and i wrote
dump($user);
die();
I'm receiving "false"...
Login.ctp:
<div class="index large-4 medium-4 large-offset-4 medium-offset-4 columns">
<div class="panel">
<center><?= $this->HTML->image('small_logo.png'); ?></center>
<?= $this->Form->create(); ?>
<?= $this->Form->input('email'); ?>
<?= $this->Form->input('password'); ?>
<center><?= $this->Form->submit('Log In', array('class' => 'button')); ?></center>
<?= $this->Form->end(); ?>
</div>
I think the issue is related with 'DefaultHasherPassword' but i dont know where is the issue and how it should be resolved. Please help.
Its like new user cant login, but when the user is modified (password changed) - he can log in.
You may be forgot to add field username as email (not sure because you didn't share your code)
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email', //email consider as username
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
]
]);
Related
I need to validate a login form but I get error on form: Notice (8): Undefined variable: user [APP/Template\Users\login.ctp, line 5]
What could be?
login.ctp:
<br>
<div class="index large-4 medium-5 large-offset-4 medium-offset-4 columns">
<div class="panel">
<h2 class="text-center">Login</h2>
<?= $this->Form->create($user); ?>
<?= $this->Form->input('email' ,array('id' =>'email')); ?>
<?= $this->Form->input('password', array('type' => 'password'), array('id' => 'password')); ?>
<?= $this->Form->submit('Login', array('class' => 'button')); ?>
<?= $this->Form->end(); ?>
</div>
</div>
login function on UsersController.php:
public function login()
{
if($this->request->is('post'))
{
$user = $this->Auth->identify();
if($user)
{
$this->Auth->setUser($user);
return $this->redirect(['controller' => 'comentario']);
}
// Erro no Login
$this->Flash->error('Erro de autenticação');
}
}
UPDATE login function located in UsersController.php
public function login()
{
$user = $this->Auth->identify();
if($this->request->is('post'))
{
if($user)
{
$this->Auth->setUser($user);
return $this->redirect(['controller' => 'comentario']);
}
// Erro no Login
$this->Flash->error('Erro de autenticação');
}
}
Auth Configuration:
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
]
]
],
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
]
]);
}
$user is a reference to a variable and is undefined in your view. If you are creating a form for users, then the standard convention would be :
<?= $this->Form->create('User'); ?>
which will implicitly post to the same action that rendered the view.
Update:
You are calling auth for the $user before you check if the form is posted, so it will throw an undefined error before the form is submitted, when the view is rendered normally. I'm not overly familiar with 3.x, so you may or may not need to explicitly pass $this->request->data to the auth function. The method should be something like the following:
public function login()
{
if($this->request->is('post'))
{
$user = $this->Auth->identify();
if($user)
{
$this->Auth->setUser($user);
return $this->redirect(['controller' => 'comentario']);
}
// Erro no Login
$this->Flash->error('Erro de autenticação');
}
else{
//do something else here
}
}
From the 3.x documentation
Identifying Users and Logging Them In AuthComponent::identify() You
need to manually call $this->Auth->identify() to identify the user
using credentials provided in request. Then use $this->Auth->setUser()
to log the user in, i.e., save user info to session.
When authenticating users, attached authentication objects are checked
in the order they are attached. Once one of the objects can identify
the user, no other objects are checked. A sample login function for
working with a login form could look like:
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Flash->error(__('Username or password is incorrect'), [
'key' => 'auth'
]);
}
}
}
I want to display username after login in cakephp3. I write follow code but part of show username doesn't work. user after login redirect to main page.
Hi <?php print $this->request->session()->read('User',$user); ?>
login in UserController:
public function login() {
if ($this->request->session()->read('login_ok') == '1') {
$this->redirect(['controller' => 'users', 'action' => 'main']);
}
if ($this->request->is('post')) {
//$hasher = new DefaultPasswordHasher();
$count = $this->Users->find()
->where(['username' => $this->request->data['username'],
// 'password' => $this->request->data['password']])
'password' => md5($this->request->data['password'])])
->count();
if ($count > 0) {
$result = true;
$this->request->session()->write('User', $user); //store username
$this->request->session()->write('login_ok', '1');
$this->redirect(['controller' => 'users', 'action' => 'main']);
} else {
$result = false;
}
$this->set('result', $result);
}
}
public function main() {
if ($this->request->session()->read('login_ok') != '1') {
$this->redirect(['controller' => 'users', 'action' => 'login']);
}
$query = $this->request->session()->write('User',$user);
$this->set('user', $query);
}
and this main.ctp codes:
Hi <?php print $this->request->session()->read('User', $user); ?>
Can you help in making this Code OR Suggest a new code ?
You should really be using the cakephp AuthComponent and the functions that's made for this for example identifiying the user trying to login with identify().
There is really no point using a framework if you're not going to use the functions provided by the framework as N Nem pointed out in the comments.
In the snippet you posted, you seem to never set the $user variable when you write to the session. You need to set it to be able to read it.
The following code is how you're supposed to do it in Cakephp 3 i really suggest you use that approach.
AppController.php
public function initialize()
{
$this->loadComponent('Auth', [
'loginAction' => [
'controller' => 'Users',
'action' => 'login'
],
'loginRedirect' => [
'controller' => 'Start',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Users',
'action' => 'login'
],
'authenticate' => [
'Form'
],
]);
}
UsersController.php
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
} else {
$this->Flash->error(__('Username or password is incorrect'), [
'key' => 'auth'
]);
}
}
}
Model/Entity/User.php
protected function _setPassword($password)
{
return (new DefaultPasswordHasher)->hash($password);
}
I'm facing trouble with my login system. I managed to register my user in my database but whenever I try to log in, it keeps prompting "Invalid email or password, try again".
This is my model:
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\Validation\Validator;
class UsersTable extends Table
{
public function validationDefault(Validator $validator)
{
return $validator
->notEmpty('email', 'A email is required')
->add('email', 'valid' , ['rule'=> 'email'])
->add('email', [
'unique' => ['rule' => 'validateUnique', 'provider' => 'table']
])
->requirePresence('email','create')
->notEmpty('password', 'A password is required')
->notEmpty('role', 'A role is required')
->add('role', 'inList', [
'rule' => ['inList', ['admin', 'author']],
'message' => 'Please enter a valid role'
]);
}
}
My controller:
<?php
namespace App\Controller;
use App\Controller\AppController;
use Cake\Event\Event;
use Cake\Network\Exception\NotFoundException;
class UsersController extends AppController
{
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['add', 'logout']);
}
public function login()
{
if ($this->request->is('post')) {
$user = $this->Auth->identify();
if ($user) {
$this->Auth->setUser($user);
return $this->redirect($this->Auth->redirectUrl());
}
$this->Flash->error(__('Invalid email or password, try again'));
}
}
public function logout()
{
return $this->redirect($this->Auth->logout());
}
public function index()
{
$this->set('users', $this->Users->find('all'));
}
public function view($id)
{
if (!$id) {
throw new NotFoundException(__('Invalid user'));
}
$user = $this->Users->get($id);
$this->set(compact('user'));
}
public function add()
{
$user = $this->Users->newEntity();
if ($this->request->is('post')) {
$user = $this->Users->patchEntity($user, $this->request->data);
if ($this->Users->save($user)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['action' => 'add']);
}
$this->Flash->error(__('Email already existed.'));
}
$this->set('user', $user);
}
}
AppController:
<?php
namespace App\Controller;
use Cake\Controller\Controller;
use Cake\Event\Event;
class AppController extends Controller
{
public function initialize()
{
$this->loadComponent('Flash');
$this->loadComponent('Auth', [
'authorize' => ['Controller'],
'loginRedirect' => [
'controller' => 'Articles',
'action' => 'index'
],
'logoutRedirect' => [
'controller' => 'Pages',
'action' => 'display',
'home'
]
]);
}
public function isAuthorized($user)
{
if (isset($user['role']) && $user['role'] === 'admin') {
return true;
}
return false;
}
public function beforeFilter(Event $event)
{
$this->Auth->allow(['index', 'view', 'display']);
}
}
login.ctp
<div class="users form">
<?= $this->Flash->render('auth') ?>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Please enter your username and password') ?></legend>
<?= $this->Form->input('email') ?>
<?= $this->Form->input('password') ?>
</fieldset>
<?= $this->Form->button(__('Login')); ?>
<?= $this->Form->end() ?>
</div>
I think the problem comes from the AppController
Have a quick look at this : CookBook CakePHP 3.0 Example Bookmarker Part 1
The login part is here : CookBook CakePHP 3.0 Example Bookmarker Part 2
Find the similarities with your project, try to make an analogy, a relation.
Thanks guys! Managed to find the answer after referring to the tutorials. Turns out i miss out
'authenticate' => [
'Form' => [
'fields' => [
'username' => 'email',
'password' => 'password'
All good now! Cheers =)
I have developed authentication mechanism in cakePHP prior to this successfully however this time i don't know what is wrongand every time I will be prompted wrong user name/password. I have used Auth component and here are details:
Model names: User,License
sample user info: username: ahmad_agha password:e10adc3949ba59abbe56e057f20f883e which is md5 of 123456
I don't know if it is important in this case or not, but i have enabled admin routing for my controllers.
AppController.php:
class AppController extends Controller {
public $components = array('DebugKit.Toolbar',
'Auth' => array(
'authenticate' => array(
'Form' => array(
'passwordHasher' => array(
'className' => 'Simple',
'hashType' => 'sha256'
)
)
)),
'Cookie');
public function beforeFilter() {
Security::setHash('md5');
$this->Auth->loginRedirect = array('controller'
=> 'licenses', 'action' => 'index');
$this->Auth->logoutRedirect = array('controller'
=> 'owners', 'action' => 'login');
$this->Auth->allow('signup', 'confirm', 'login', 'logout', 'notauthorized', 'display');
$this->Auth->authorize = array('controller');
$this->set('loggedIn', $this->Auth->user('id'));
$this->Auth->userScope = array('User.activated' => '1');
parent::beforeFilter();
}
public function isAuthorized($user) {
// Here is where we should verify the role and give access based on role
return true;
}
}
Login.ctp for User's View
<div class="users form">
<?php echo $this->Session->flash('auth'); ?>
<?php echo md5('136112'); ?>
<?php echo $this->Form->create('User', array('action' => 'login')); ?>
<fieldset>
<legend>
<?php echo __('لطفا نام کاربری و کلمه عبور را وارد کنید'); ?>
</legend>
<?php
echo $this->Form->input('username',array('label'=>'نام کاربری'));
echo $this->Form->input('password',array('label'=>'کلمه عبور'));
echo $this->Form->input('remember_me',array('label'=>'مرا به خاطر بسپار','type'=>'checkbox'));
?>
</fieldset>
<?php echo $this->Form->end(__('ورود')); ?>
</div>
and here is the login() action of UsersController.php:
function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
/* if (!empty($this->data)) {
if (empty($this->data['User']['remember_me'])) {
$this->Cookie->delete('User');
} else {
$cookie = array();
$cookie['username'] = $this->data['User']
['username'];
$cookie['password'] = $this->data['User']
['password'];
$this->Cookie->write('User', $cookie, true, '+2 weeks');
}
unset($this->data['User']['remember_me']);
} */
$this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
}
You say your password is md5 hashed while in config for Auth you have set 'hashType' => 'sha256'. So the mismatch of hash types is quite obvious. Setting Security::setHash('md5') isn't going to do anything since the hashtype set in Auth config will take priority.
You need to change the hashType to md5. Also simply saving md5 hash of password in db won't work since password hasher appends a salt (Security.salt specified in your core.php) to the password before hashing. So do (new SimplePasswordHasher)->hash('123456') to get the hashed value which need to be stored in db. All this is explained in the CakePHP manual btw.
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');
}