I am using the github repository code here: https://github.com/hunzinker/CakePHP-Auth-Forgot-Password
I have used the following function in my UsersController.php. I get the error Undefined index: token on the line that has a comment before it. What should I change?
/**
* Allow user to reset password if $token is valid.
* #return
*/
function reset_password_token($reset_password_token = null) {
if (empty($this->data)) {
$this->data = $this->User->findByResetPasswordToken($reset_password_token);
if (!empty($this->data['User']['reset_password_token']) &&
!empty($this->data['User']['token_created_at']) &&
$this->__validToken($this->data['User']['token_created_at'])
) {
$this->data['User']['id'] = null;
$_SESSION['token'] = $reset_password_token;
} else {
$this->Session->setflash(
'The password reset request has either expired or is invalid.'
);
$this->redirect('/users/login');
}
} else {
//ERROR ON THE NEXT LINE HERE UNDEFINED INDEX: TOKEN
if ($this->data['User']['reset_password_token'] != $_SESSION['token']) {
$this->Session->setflash(
'The password reset request has either expired or is invalid.'
);
$this->redirect('/users/login');
}
$user = $this->User->findByResetPasswordToken(
$this->data['User']['reset_password_token']
);
$this->User->id = $user['User']['id'];
if ($this->User->save($this->data, array('validate' => 'only'))) {
$this->data['User']['reset_password_token'] =
$this->data['User']['token_created_at'] = null;
if ($this->User->save($this->data) &&
$this->__sendPasswordChangedEmail($user['User']['id'])
) {
unset($_SESSION['token']);
$this->Session->setflash(
'Your password was changed successfully. Please login to continue.'
);
$this->redirect('/users/login');
}
}
}
}
You need to be sure that $_SESSION contains this index, so you should update it like this in order to be sure it exists:
By this:
if (!isset($_SESSION['token']) || $this->data['User']['reset_password_token'] != $_SESSION['token']) {
$this->Session->setflash(
'The password reset request has either expired or is invalid.'
);
$this->redirect('/users/login');
}
Related
I have been getting back into Codeigniter as support was picked up by BCIT. I have a problem with ci_sessions and the database driver which is regenerating the encrypted session ID and storing new data in my database on every page refresh. I'm so frustrated right now! I have both secure file storage and database for both common drivers. I want to use both or either but the effect on my application is the same whether I am using a database or files. The ci_session keeps refreshing and it is not ideal for logins, registration or any account type. Please help me see what I am doing wrong? Much appreciation granted in advance.
Config:
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 7200;
$config['sess_save_path'] = 'users';
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = FALSE;
Controllers:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
* User Management class created by CodexWorld
*/
class Limousers extends CI_Controller {
function __construct() {
parent::__construct();
$this->load->library('form_validation');
$this->load->model('user');
}
/*
* User account information
*/
public function account(){
print_r($_SESSION);
$data = array();
print_r($this->session->userdata());
if($this->session->userdata('isUserLoggedIn')){
$data['user'] = $this->user->getRows(array('id'=>$this->session->userdata('userId')));
//load the view
$this->load->view('limousers/account', $data);
}else{
redirect('limousers/login');
exit;
}
}
/*
* User login
*/
public function login(){
print_r($_SESSION);
if($this->session->userdata('isUserLoggedIn'))
{
print_r($this->session->userdata);
redirect('limousers/account');
exit;
}
$data = array();
if($this->session->userdata('success_msg')){
$data['success_msg'] = $this->session->userdata('success_msg');
$this->session->unset_userdata('success_msg');
}
if($this->session->userdata('error_msg')){
$data['error_msg'] = $this->session->userdata('error_msg');
$this->session->unset_userdata('error_msg');
}
if($this->input->post('loginSubmit')){
$this->form_validation->set_rules('email', 'Email', 'required|valid_email');
$this->form_validation->set_rules('password', 'password', 'required');
if ($this->form_validation->run() == true) {
$con['returnType'] = 'single';
$con['conditions'] = array(
'email'=>$this->input->post('email'),
'password' => md5($this->input->post('password')),
'status' => '1'
);
$checkLogin = $this->user->getRows($con);
if($checkLogin){
$this->session->set_userdata('name',$con['conditions']['email']);
$this->session->set_userdata('isUserLoggedIn',TRUE);
$this->session->set_userdata('userId',$checkLogin['id']);
redirect('limousers/account');
exit;
}else{
$data['error_msg'] = 'Wrong email or password, please try again.';
}
}
}
//load the view
$this->load->view('limousers/login', $data);
}
/*
* User registration
*/
public function registration(){
print_r($_SESSION);
$data = array();
$userData = array();
if($this->input->post('regisSubmit')){
$this->form_validation->set_rules('name', 'Name', 'required');
$this->form_validation->set_rules('email', 'Email', 'required|valid_email|callback_email_check');
$this->form_validation->set_rules('password', 'password', 'required');
$this->form_validation->set_rules('conf_password', 'confirm password', 'required|matches[password]');
$userData = array(
'name' => strip_tags($this->input->post('name')),
'email' => strip_tags($this->input->post('email')),
'password' => md5($this->input->post('password')),
'gender' => $this->input->post('gender'),
'phone' => strip_tags($this->input->post('phone'))
);
if($this->form_validation->run() == true){
$insert = $this->user->insert($userData);
if($insert){
$this->session->set_userdata('success_msg', 'Your registration was successfully. Please login to your account.');
redirect('limousers/login');
exit;
}else{
$data['error_msg'] = 'Some problems occured, please try again.';
}
}
}
$data['user'] = $userData;
//load the view
$this->load->view('limousers/registration', $data);
}
/*
* User logout
*/
public function logout(){
$this->session->unset_userdata('isUserLoggedIn');
$this->session->unset_userdata('userId');
$this->session->sess_destroy();
redirect('limousers/login');
exit;
}
/*
* Existing email check during validation
*/
public function email_check($str){
$con['returnType'] = 'count';
$con['conditions'] = array('email'=>$str);
$checkEmail = $this->user->getRows($con);
if($checkEmail > 0){
$this->form_validation->set_message('email_check', 'The given email already exists.');
return FALSE;
} else {
return TRUE;
}
}
}
Models:
<?php if ( ! defined('BASEPATH')) exit('No direct script access
allowed');
class User extends CI_Model{
function __construct() {
$this->userTbl = 'users';
}
/*
* get rows from the users table
*/
function getRows($params = array()){
$this->db->select('*');
$this->db->from($this->userTbl);
//fetch data by conditions
if(array_key_exists("conditions",$params)){
foreach ($params['conditions'] as $key => $value) {
$this->db->where($key,$value);
}
}
if(array_key_exists("id",$params)){
$this->db->where('id',$params['id']);
$query = $this->db->get();
$result = $query->row_array();
}else{
//set start and limit
if(array_key_exists("start",$params) &&
array_key_exists("limit",$params)){
$this->db->limit($params['limit'],$params['start']);
}elseif(!array_key_exists("start",$params) &&
array_key_exists("limit",$params)){
$this->db->limit($params['limit']);
}
$query = $this->db->get();
if(array_key_exists("returnType",$params) &&
$params['returnType'] == 'count'){
$result = $query->num_rows();
}elseif(array_key_exists("returnType",$params) &&
$params['returnType'] == 'single'){
$result = ($query->num_rows() > 0)?$query- >row_array():FALSE;
}else{
$result = ($query->num_rows() > 0)?$query->result_array():FALSE;
}
}
//return fetched data
return $result;
}
/*
* Insert user information
*/
public function insert($data = array()) {
//add created and modified data if not included
if(!array_key_exists("created", $data)){
$data['created'] = date("Y-m-d H:i:s");
}
if(!array_key_exists("modified", $data)){
$data['modified'] = date("Y-m-d H:i:s");
}
//insert user data to users table
$insert = $this->db->insert($this->userTbl, $data);
//return the status
if($insert){
return $this->db->insert_id();
}else{
return false;
}
}
}
I am creating an Angularjs app with Symfony 2.8 on the backend, using FOSUser bundle for the user management.
I have a controller to check the user login and create the user session, but when i try to create the user session symfony returns me this error message:
Controller "UserBundle\Controller\LoginController::indexAction()" requires that you provide a value for the "$session" argument (because there is no default value or because there is a non optional argument after this one).
There is my controller code:
<?php
namespace UserBundle\Controller;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Session\Session;
use UserBundle\Entity\User;
class LoginController extends Controller
{
public function indexAction(Session $session)
{
$arrResult = array('STATUS' => 'ERROR', 'ERROR' => 'INIT', 'DATA' => array() );
// get post data
$postData = file_get_contents("php://input");
$postData = json_decode($postData, TRUE);
$email = $postData['email'];
$password = $postData['password'];
if( empty($email) || empty($password) )
{
$arrResult['ERROR'] = 'ALL_FIELDS_ARE_REQUIRED';
return new JsonResponse($arrResult);
}
$user_manager = $this->get('fos_user.user_manager');
$factory = $this->get('security.encoder_factory');
$user = $user_manager->findUserByEmail($email);
$encoder = $factory->getEncoder($user);
$salt = $user->getSalt();
if( $encoder->isPasswordValid($user->getPassword(), $password, $salt) )
{
// create user session
$this->createLoginSession($session, $user);
$arrResult['DATA'] = array('USERNAME' => $user->getUsername());
$arrResult['STATUS'] = 'OK';
}
else
{
$arrResult['ERROR'] = 'INVALID_CREDENTIALS';
}
return new JsonResponse($arrResult);
}
private function createLoginSession($session, $objUser)
{
$objToken = new UsernamePasswordToken($objUser, null, 'main', $objUser->getRoles() );
// save token
$objTokenStorage = $this->get("security.token_storage")->setToken($objToken);
$session->set( '_security_main', serialize($objToken) );
}
}
What i am doing wrong?
Thanks!
How to update user information stored in auth session? without logout and login again.
I think this function will do it.. but is it the best-practice?
function update($field, $value){
$this->Session->write($this->Auth->sessionKey . '.' . $field, $value);
}
Yes.
You could grab the current info array, modify it, and then call $this->Auth->login($newUserData);, but this will also renew the session (no user interaction needed, though). Note: Applies to CakePHP 2.0+ only.
I've completed update function to get an array of new values. with keys (field name):
public function update($fields, $values = null) {
if (empty(parent::$_user) && !CakeSession::check(parent::$sessionKey)) {
return false;
}
if (!empty(parent::$_user)) {
$user = parent::$_user;
} else {
$user = CakeSession::read(parent::$sessionKey);
}
if (is_array($fields)) {
if (is_array($values)) {
$data = array_combine($fields, $values);
} else {
$data = $fields;
}
} else {
$data = array($fields => $values);
}
foreach ($data as $field => $value) {
if (isset($user[$field])) {
$user[$field] = $value;
}
}
return $this->login($user);
}
(thanks to tigrang for login function)
How to match new_password and confirm_password fields when they are not in database?
Hi... I would like to know how I would be able to match my fields "new_password" and "confirm_password", they are not stored in database they are just used for matching purpose in Change Password module.
I tried this but it didn't worked:
if($this->data['User']['new_password'] != $this->data['User']['confirm_password'] ) {
$this->Session->setFlash("New password and Confirm password field do not match");
} else {
$this->data['User']['password'] = $this->data['User']['new_password'];
$this->data['User']['id'] = $this->User->id;
if($this->User->save($this->data)) {
$this->Session->setFlash("Password updated");
$this->redirect('/users/login');
}
}
You can try this:
// check for empty value
if( !empty( $this->data['User']['new_password'] ) && !empty( $this->data['User']['confirm_password'] ) ) {
if( $this->data['User']['new_password'] != $this->data['User']['confirm_password']) {
$this->Session->setFlash("New password and Confirm password field do not match");
} else {
$this->data['User']['password'] = $this->data['User']['new_password'];
$this->data['User']['id'] = $this->User->id;
if( $this->User->save($this->data) ) {
$this->Session->setFlash("Password updated");
$this->redirect('/users/login');
} else {
$this->Session->setFlash('Password update fail');
}
}
} else {
$this->Session->setFlash('Enter New password and Confirm password');
}
i tried to send activation code to user mail (currently gmail) from localhost.. when submit the user information saved in database but the message not sent..so why not sent ?
var $components = array('Email','Auth','Recaptcha');
// Allows a user to sign up for a new account
function register () {
if (!empty($this->data)) {
// See my previous post if this is forgien to you
if($this->data['User']['password'] == $this->Auth->password($this->data['User']['password_confirm'])){
$this->User->data = Sanitize::clean($this->data);
// Successfully created account - send activation email
if($this->Recaptcha->valid($this->params['form'])){
if ($this->User->save()) {
$this->__sendActivationEmail($this->User->getLastInsertID());
$this->Session->setFlash('activation code sent check your mail');
$this->redirect('/users/register');
}else {
$this->data['User']['password'] = null;
}
}else{
$this->data['User']['password'] = null;
$this->Session->setFlash('wrong captcha please try again');
}
}else{
$this->data['User']['password'] = null;
$this->Session->setFlash('password not match');
}
}
}
this function Send out an activation email to the user.id specified by $user_id
#param Int $user_id User to send activation email to
#return Boolean indicates success
function __sendActivationEmail($user_id) {
$user = $this->User->find(array('User.id' => $user_id), array('User.id','User.email', 'User.username'), null, false);
if ($user === false) {
debug(__METHOD__." failed to retrieve User data for user.id: {$user_id}");
return false;
}
// Set data for the "view" of the Email
$this->set('activate_url', 'http://' . env('SERVER_NAME') . '/cakenews/users/activate/' . $user['User']['id'] . '/' . $this->User->getActivationHash());
$this->set('username', $this->data['User']['username']);
$this->Email->to = $user['User']['email'];
$this->Email->subject = env('SERVER_NAME') . ' - Please confirm your email address';
$this->Email->from = 'spcialist#gmail.com';
$this->Email->template = 'user_confirm';
$this->Email->delivery = 'smtp';
$this->Email->smtpOptions = array(
'port'=>'465',
'timeout'=>'30',
'host' => 'ssl://smtp.gmail.com',
'username'=>'spcialist#gmail.com',
'password'=>1234567,
);
$this->Email->sendAs = 'text'; // you probably want to use both :)
return $this->Email->send();
}
You wrote you are on localhost, you probably can't send emails but will probably work once online.
try debugging
function __sendActivationEmail($user_id) {
$this->Email->delivery = 'debug';
....
}
Then in your layout
<?php echo $this->Session->flash('email'); ?>
And see what comes out.