I'm struggling with a problem. I use the Phalcon framework.
The problem is, the $this->security->checkHash() function always returns false.
What I've checked so far:
Checked the length of the varchar password field (is 255) so the hash should fit perfectly inside the field.
Currently, the code looks like this:
The register function:
public function registerAction()
{
$postData = $this->request->getPost();
/*
* Validation
*/
$validation = new RegistrationValidation();
$validationMessages = $validation->validate($postData);
if (count($validationMessages)) {
// Validation Failed!
foreach ($validationMessages as $message)
$this->flashSession->error( $message);
$this->response->redirect( $_SERVER['HTTP_REFERER'] );
$this->response->send();
} else {
// Check Passwords Match
if($postData['password'] !== $postData['password-repeat']) {
$this->flashSession->error( "Passwords don't match");
$this->response->redirect( $_SERVER['HTTP_REFERER'] );
$this->response->send();
}
}
/**
* Begin registration Process
*/
$user = new Users();
$password = $this->request->getPost('pawword');
$password = $this->security->hash($password);
$user->username = $this->request->getPost('username');
$user->email = $this->request->getPost('email');
$user->register_ip = $_SERVER['REMOTE_ADDR'];
$user->password = $password;
$user->active = 0;
// Store user
$user->save();
$this->view->emailmsg = $this->sendVerificationMail($user->id, $user->email, $user->username);
}
the login function:
public function loginAction()
{
if ($this->request->isPost()) {
$email = $this->request->getPost("email");
$password = $this->request->getPost("password");
var_dump($password);
$user = Users::findFirstByEmail($email);
var_dump($this->security->checkHash( 'edrsvc', '$2y$12$ZERPY2Q3N0hUdG1XSkw5V.DqhYek97IZyrRQwq/UP/X7xO3PiPIpG' ));
var_dump($this->security->checkHash($password, $user->password));
var_dump(password_verify('edrsvc', '$2y$12$ZERPY2Q3N0hUdG1XSkw5V.DqhYek97IZyrRQwq/UP/X7xO3PiPIpG'));
die();
if ($user) {
if ($this->security->checkHash($password, $user->password)) {
var_dump($user);
die();
$this->_registerSession($user);
$this->flash->success(
"Welcome " . $user->name
);
// Forward to the 'invoices' controller if the user is valid
$this->dispatcher->forward(
[
"controller" => "index",
"action" => "index",
]
);
}
} else {
$this->security->hash(rand());
$this->flashSession->error(
'Wrong Email or password Back'
);
}
}
}
You can see those 3 var_dumps, which are actually functioning and not throwing exceptions, but always return false. The password is of course
correct and checked twice.
The workFactor is set to Phalcon's default workFactor.
Related
i try to create function for change password member via Dashboard Admin, and when i am trying to do a login then get this error, and i am sure i enter correct values
this is my function for update member password
public function update(Request $request, $id)
{
$rules = array(
'username' => 'required|unique:members,username,'.$id,
'email' => 'required|unique:members,email,'.$id,
'password' => 'min:8',
'retype_password' => 'min:8|same:password'
);
$validator = Validator::make(Input::all(), $rules);
// process the login
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
} else {
// Input
$username = Input::get('username');
$email = Input::get('email');
$now = new DateTime();
// get old password
$members = members::where('id',$id)->first();
if (!empty('password') && !empty('retype_password')) {
$password = $members->password;
}else{
$password = bcrypt(Input::get('password'));
}
// store
$store = members::find($id);
$store->status = 1;
$store->username = $username;
$store->email = $email;
$store->password = $password;
$store->updated_at = new DateTime();
$store->save();
// redirect
return redirect('system/members')->with('success','Data successfully updated');
}
}
and this is Model members
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Notifications\MemberResetPasswordNotification;
class members extends User
{
protected $table = "members";
protected $fillable = [
'username', 'email', 'password',
];
/**
* Send the password reset notification.
*
* #param string $token
* #return void
*/
public function sendPasswordResetNotification($token)
{
$this->notify(new MemberResetPasswordNotification($token));
}
}
this is my login function :
public function login(Request $request)
{
$this->validateLogin($request);
// If the class is using the ThrottlesLogins trait, we can automatically throttle
// the login attempts for this application. We'll key this by the username and
// the IP address of the client making these requests into this application.
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if ($this->attemptLogin($request)) {
return $this->sendLoginResponse($request);
}
// If the login attempt was unsuccessful we will increment the number of attempts
// to login and redirect the user back to the login form. Of course, when this
// user surpasses their maximum number of attempts they will get locked out.
$this->incrementLoginAttempts($request);
return $this->sendFailedLoginResponse($request);
}
any solutions for me?
Change the logic (if/else) and there is no field like empty('password') and empty('retype_password')
if (!empty(Input::get('password')) && !empty(Input::get('retype_password'))) {
# new password
$password = Hash::make(Input::get('password'));
}else{
# old Password
$password = $members->password;
}
Make sure this use Illuminate\Support\Facades\Hash; on top
And password re-check Laravel has the easiest way to do it.
In Form
<input type="password" name="password" >
<input type="password" name="password_confirmation" > # this should be password_confirmation retype_password filed in yours
In controller
Just add this rule
'password' => 'required|min:8|confirmed', # just add confirmed thats it
Edit
Use this to login
$username = Input::get('username');
$password = Input::get('password');
if (!Auth::attempt([ 'email' => $username, 'password' => $password])) {
# error
Session::flash('error', 'Invalid Username or Password !');
return Redirect::to('admin');
}
else {
# success
return Redirect::to('admin/dashboard');
}
You should change your logic:
if (empty($request->password) && empty($request->retype_password)) {
$password = $members->password;
}else{
$password = bcrypt(Input::get('password'));
}
I think you could use the if condition like this
if ($request->input('password') && $request->input('retype_password')) {
$password = bcrypt($request->input('password'));
}else{
$password = $members->password;
}
Hope this helps
CakePHP version: 3.3.5
I'm building a simple system using which users can login (using a email and password) and after login they can change their password.
For this, I'm using DefaultPasswordHasher
I had a few users already in my db. Their record were already present. So when I did the login function, it worked. I compared the password the user enters with the hased password already present in the db. The check was successful and user was able to login.
Now after login, I wrote change password function, which updated the user password. New hash string replaced the old password string but when I try to login again, login fails.
I will share my controller here. It's pretty basic.
namespace Api\Controller;
use Cake\Utility\Security;
use Cake\Utility\Hash;
use Cake\Auth\DefaultPasswordHasher;
use Api\Controller\AppController;
class LoginController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
}
//Function to reset the password
public function resetPassword()
{
$pass = $this->request->data['pass'];
$hasher = new DefaultPasswordHasher();
$hashedPass = $hasher->hash($pass);
$this->loadModel('Login');
//save it to db
$responseArray = $this->Login->resetPassword($hashedPass);
$this->set(compact('responseArray'));
$this->set('_serialize', ['responseArray']);
}
//Function to login
public function login()
{
if ($this->request->is('post'))
{
//Password submitted via form
$pass = $this->request->data['pass'];
//Hashed password fetched from db via a function call
$actualPassword = 'hashedPasswordString'
//Compare password submitted and hash from db
if($this->checkPassword($pass,$actualPassword))
{
$result = 'password matched';
}
else
{
$result = 'password doesnot match';
}
}
$this->set(compact('result'));
$this->set('_serialize', ['result']);
}
//Function to compare password and hash
public function checkPassword($passedPassword , $actualPassword)
{
if ((new DefaultPasswordHasher)->check($passedPassword, $actualPassword)) {
return true;
} else {
return false;
}
}
}
Can anyone tell me why the passwords don't match. I'm new to CakePHP framework. Thanks in advance!
This is what my reset password workflow looks like. I cannot tell from your post what your entity and table look like.
Anytime posted data is converted into a user entity it will now be hashed
Admin/UsersController.php
public function password($id = null)
{
$user = $this->Users->get($id, [
'fields' => ['id', 'first_name', 'last_name', 'username']
]);
if ($this->request->is('put')) {
if ($this->request->data['password'] == $this->request->data['password2']) {
$this->Users->patchEntity($user, ['password' => $this->request->data['password']]);
$this->Users->save($user);
$this->Flash->success('Password has been updated');
return $this->redirect('/admin/users/password/' . $id);
} else {
$this->Flash->error('Passwords do not match');
}
}
$this->set(compact('user'));
}
Model/Entity/User.php
protected function _setPassword($password)
{
if (strlen($password) > 0) {
return (new DefaultPasswordHasher)->hash($password);
}
}
public function changePassword(){
if ($this->request->is('post')) {
$data = $this->request->data();
$res['success'] = FALSE;
$user = $this->Users->get($this->Auth->user('id'))->toArray();
if ((new DefaultPasswordHasher)->check($data['oldPassword'], $user['password'])) {
if($data['newPassword'] == $data['confPassword']){
$userEntity = $this->Users->get($this->Auth->user('id'));
$userEntity->password = $data['newPassword'];
if($this->Users->save($userEntity)){
$res['success'] = TRUE;
$res['message'] = 'Password Changed Successfully.';
}
}else{
$res['success'] = FALSE;
$res['message'] = 'Confirm password is not same as new password. please enter both password again!!';
}
}else{
$res['success'] = FALSE;
$res['message'] = 'Your old password is wrong!';
}
echo json_encode($res);
exit();
}
}
I am new in yii2, Right now i am working with custom login, i did all code for login but when i go in home page through index action i didn't get any session there, Here is my code
public function actionIndex()
{
$session = Yii::$app->session;
if ($session->isActive) {
echo 'sdsd'; die;
}
return $this->render('index');
}
public function actionLogin()
{
if (!\Yii::$app->user->isGuest) {
return $this->goHome();
}
$model = new User();
//if ($model->load(Yii::$app->request->post()) && $model->login()) {
if ($model->load(Yii::$app->request->post()) && $model->validate()) {
$userName = $_POST['User']['UserName'];
$password = $_POST['User']['Password'];
$condition = "UserName = '".$userName."' AND Password = '".md5($password)."' AND Status = '1' AND UserType = '1' ";
$loginData = User::find()->where($condition)->all();
if(count($loginData)>0) {
$username = $loginData[0]->UserName;
$userID = $loginData[0]->UserID;
$session = Yii::$app->session;
$session->set('userName',$username);
$session->set('userID',$userID);
$this->redirect('index');
} else {
Yii::$app->session->setFlash('error', 'Username or password is incorrect');
}
}
return $this->render('login', [
'model' => $model,
]);
}
Even after login it still consider me as guaest user, Yii::$app->user->isGuest what changes i need to do now ?
You don't login the user in Yii App
You don't need set the session you must assign the proper value to this function
return \Yii::$app->getUser()->login($yourUser, $yourRememberMe ? $this->module->rememberFor : 0);
see this doc for user and this for login
I have a protected $headers variable in my class assigning a value using the function
public function actionLogIn()
{
$userCode = Input::get('username');
$password = Input::get('password');
$loginData = array(
'code' => $userCode,
'passkey' => $password
);
$loginData = json_encode($loginData);
$this->headers = Auth::login($loginData);//Modified login method
if(! is_null($this->headers))
{
return View::make('forms.welcome')->with('title', 'Welcome');
}else{
echo "Invalid access!";
}
}
and when I use print_r($this->headers); it successfully prints out the value I need,
but when I tried to access $this->headers using the function:
public function actionLogOut()
{
if(is_null($this->headers)){
echo "is null", "\n";
}//for checking only
Auth::logout($this->headers);
}
$this->headers is null. What could be the problem ? also $headers is actually an array. Thanks!
A new controller instance is created for every request. That means that even though you store information in $this, it's not there when the user requests a new page.
What you want to do is store data in something that doesn't change between requests - either in the session or in cookies.
In the session, it would look like this: (warning - untested code)
public function actionLogIn() {
...
$loginData = json_encode($loginData);
$user = Auth::login($loginData);
if ($user) {
Session::put('logged_in_user',$user);
return View::make('forms.welcome')->with('title', 'Welcome');
}else{
echo "Invalid access!";
}
}
public function actionLogOut() {
if(Session::has('logged_in_user'){
$user = Session::get('logged_in_user');
Auth::logout($user);
Session::forget('logged_in_user');
} else {
echo "is null\n";
}
}
Take a look at http://four.laravel.com/docs/session for more information on Sessions in Laravel.
I have a log in form that checks the user email and password through the database, if it matches, it allow the user to log in. The problem is it checks the email that matches any password in the database or the password that matches any emails in the database. I want it to check this specific user email to match his password, not matches any password that exists in database.
Here's my controller that I think I did it wrong:
$loginForm = new Application_Form_UserLogin();
if ($this->getRequest()->isPost('loginForm'))
{
$email_adrress = $this->getRequest()->getParam('email_address');
$password = $this->getRequest()->getParam('password');
/************ Login Form ************/
if ($loginForm->isValid($this->getRequest()->getParams()))
{
$user = $this->_helper->model('Users')->createRow($loginForm->getValues());
$user = $this->_helper->model('Users')->fetchRowByFields(array('email' => $email_adrress, 'hash' => $password));
if($user)
{
Zend_Session::rememberMe(86400 * 14);
Zend_Auth::getInstance()->getStorage()->write($user);
$this->getHelper('redirector')->gotoRoute(array(), 'invite');
return;
}
else {
}
}
}$this->view->loginForm = $loginForm;
My form:
class Application_Form_UserLogin extends Zend_Form
{
public $email, $password, $submit;
public function init()
{
$this->setName('loginForm');
$EmailExists = new Zend_Validate_Db_RecordExists(
array(
'table' => 'users',
'field' => 'email'
)
);
//$EmailExists->setMessage('Invalid email address, please try again. *');
$PasswordExists = new Zend_Validate_Db_RecordExists(
array(
'table' => 'users',
'field' => 'hash'
)
);
$PasswordExists->setMessage('Invalid password, please try again. *');
$this->email = $this->createElement('text', 'email_address')
->setLabel('Email')
->addValidator($EmailExists)
->addValidator('EmailAddress')
->setRequired(true);
$this->password = $this->createElement('text', 'password')
->setLabel('Password')
->addValidator($PasswordExists)
->setRequired(true);
$this->submitButton = $this->createElement('button', 'btn_login')
->setLabel('Login')
->setAttrib('type', 'submit');
$this->addElements(array($this->email, $this->password, $this->submit));
$elementDecorators = array(
'ViewHelper'
);
$this->setElementDecorators($elementDecorators);
}
}
I wouldn't add this login processing as a validator on one of the elements. Instead, I would create an Zend_Auth authentication adapter with your User model, email, and password as constructor arguments. Then, in controller, call Zend_Auth::authenticate($adapter).
Something like:
class Application_Model_AuthAdapter implements Zend_Auth_Adapter_Interface
{
protected $userModel;
protected $email;
protected $pass;
public function __construct($userModel, $email, $pass)
{
$this->userModel = $userModel;
$this->email = $email;
$this->pass = $pass;
}
public function authenticate()
{
$user = $this->userModel->getByEmailAndPassword($this->email, $this->pass);
if ($user){
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user);
} else {
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null);
}
}
}
Then in your controller:
public function loginAction()
{
$form = new Application_Form_UserLogin();
if ($this->_request->isPost()) {
if ($form->isValid($this->_request->getPost())) {
$data = $form->getValues();
$email = $data['email'];
$pass = $data['pass'];
$userModel = $this->_helper->model('Users');
$authAdapter = new Application_Model_AuthAdapter($userModel, $email, $pass);
$result = Zend_Auth::getInstance()->authenticate($adapter);
if ($result->isValid()){
// $user= $result->getIdentity(). Use it how you like.
// Redirect someplace
} else {
$this->view->error = 'Invalid login';
}
}
}
$this->view->form = $form;
}
See Zend_Auth reference for more details.
I'm not familiar with the way you're trying to do it. Is the fetchRowByFields method one you have written yourself? If so, it's difficult to help you without seeing the code.
Have you considered using the mechanism provided by Zend Framework to perform authentication against a database?
The Zend Framework official manual contains a brief tutorial on how to implement authentication:
http://framework.zend.com/manual/1.12/en/learning.multiuser.authentication.html
You use an adapter with the Zend_Auth class to do what you want.