[Yii 1]Encriptar contrasena y enviar por correo.

Hola,

tengo que enviar la contrasena de usuario cuando el mismo usuario se ha perdido su contrasena.

He creado la funcion por el envio de correos y todo sale bien.

Pero tengo un problema.

Es que cuando el usuario se registra le guardo la contrasena criptada en la accion con esto:




...............

$model->password=$model->hashPassword($_POST['User']['password'], $session=$model->generateSalt());

...............



y en el model User con estas reglas:





public function validatePassword($password)

{

	return $this->hashPassword($password,$this->session)===$this->password;

	

	}




public function hashPassword($password,$salt)

{

	return md5($salt.$password);

	

	}




public function generateSalt()

{

	return uniqid('',true);

	

	}




En tonces cuando el se va a recuperar su contrasena le llega criptada por correo.

Como puedo hacer para que le llegue encriptada?

Si no me equivoco no se puede encriptar este tipo de criptacion ( o mejor se puede gracias a algunos sitios de base datos criptados). Pero tambien quiero que la contrasena sea criptada. Ahora tengo dos soluciones:

  1. no cripto la contrasena -> tampoco es bueno.

  2. le genero una nueva contrasena antes que salga la mail -> no se como realizarlo. Seria un beforeSave?

Esta es mi accion para recuperar su contrasena:




//RECUPERO PASSWORD FORM

	public function actionRecuperoPassword()

	{

	

		$model=new RecuperoPassword;

		$msg = '';

		

		if (isset($_POST["RecuperoPassword"]))

		{

			 

			$model->attributes = $_POST['RecuperoPassword'];

			if(!$model->validate())

			{

			$msg = "<strong class='text-error'>Errore durante 1\' invio del Form</strong>";	

			//print_r($msg);

				}

				else

				{

					$connessione = Yii::app()->db;

					//verifica se esiste l username

					$ricerca = "SELECT username, email FROM user WHERE ";

					$ricerca .= "username='".$model->username."' AND email='$model->email'";

					$risultato =  $connessione->createCommand($ricerca);


					$righe = $risultato->query();

					$esiste = false;

					

					foreach ($righe as $riga)

					{

						$esiste = true;

						}

						//se l' username esiste

						if ($esiste === true)

						{

							//Trova la sua password

					$ricerca = "SELECT password FROM user WHERE ";

					$ricerca .= "username='".$model->username."' AND email='".$model->email."'"; 

					

					$risultato =  $connessione->createCommand($ricerca)->query();

						

					$risultato->bindColumn(1, $password);

					

					while($risultato->read()!==false)

					{

						$password = $password;

					}

					

					$email = new InviaEmail;

									

					$subject = "Hai richiesto il recupero della tua password";

					$subject .= Yii::app()->name;

					$message = "Benvenuto"  .$model->username.  "questa è la tua password" ;

					$message .= $password;

					$message .= "<br />";

					$message .="<a href='http://localhost/sito/'>Vai al Sito</a>";

					

					$email->Invia_Email

					(

						array(Yii::app()->params['adminEmail'], Yii::app()->name),

						array($model->email, $model->username),


						$subject,

						$message

						);

						$model->username ='' ;

						$model->email  = '' ;

						$model->captcha = '' ;

						$msg = "<strong  class='text-info'>La password ti è stata inviata via email</strong>";

				  }

				  else{

					  $msg = "<strong class='text-error'>Non è stato trovato nessun utente con le credenziali inserite nel form. Contatta l' amministratore</strong>";

					  }

			 }

		}

		

		

		$this->render('recuperopassword', array('model'=>$model, 'msg'=>$msg));

		}



En esos casos lo que se hace es encriptar la contraseña y cuando el usuario pierde su contraseña se le envía una url por correo y cuando abra la url se le muestra una pantalla donde debe capturar la nueva contraseña, la url debe ser unica por usuario y por ocación, es decir cada vez que pierda la contraseña la url que le envies seria diferente. Tambien podrias limitar el tiempo en el que el usuario pueda usar la url verificando que la fecha en que se abre la url no sea mayor a una semana desde la creación de la url por ejemplo.

Hola a18327,

y gracias por tu respuesta.

Podrias esplicarme como puedo hacer esto por favor, por que aun he ententado pero no me sale.

Muchas gracias :)

Lo que tendrias que hacer es lo siguiente

  1. Debes crear un Model para las claves de recuperación de contraseñas por ejemplo PasswordRecovery, los campos minimos que debe tener son user_id, code, expiry_date y status.

  2. En el nuevo Model debes poner la relación con el usuario por ejemplo


public function relations() {		

    return array (

        'user'=>array(self::BELONGS_TO,'User','user_id'),

    );

}

  1. Debes crear una vista de recuperación de contraseñas (ya la tienes) donde tengas un botón que envie un correo al usuario con la url donde pueda cambiar el su contraseña, la url seria algo como http://miaplicacionyii.com/user/changePassword/code/8s76dh3kd997dd883d00d8 donde changePassword es un action en el controlador UserController(o como se llame tu controlador de usuarios).

  2. El code lo puedes generar concatenando el nombre del usuario, la fecha y hora y un salt aleatorio. por ejemplo.


$str="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

$salt="";

for($i=1;$i<20;$i++){

    $s=rand(0,51);

    $salt.=$str[$s];

}

$time=substr(md5($millitime = round(microtime(true) * 1000)),0,<img src='http://www.yiiframework.com/forum/public/style_emoticons/default/cool.gif' class='bbc_emoticon' alt='8)' />;

$code=hash ( 'sha256', $salt . $user->username . $time);

$url=Yii::app()->createAbsoluteUrl("user/changePassword",array('code'=>$code));

$modelPR=new PasswordRecovery();

$modelPR->code=$code;

$modelPR->user_id=$user->id;

$modelPR->expire_date=date("Y/m/d H:i:s",strtotime("+7 DAYS"));

$modelPR->status=1;//1 Activo, 0 Inactivo

$modelPR->save();



Donde $user->username es el usuario que quiere resetear su contraseña

  1. El action changePassword del controlador del usuario debe recibir el codigo y verificar que el usuario puede cambiar su contraseña por ejemplo

public function actionChangePassword($code){

    $modelPR=PasswordRecovery::model()->find("status=1 AND code=:code AND expire_date<:date",array(':code'=>$code,':date'=>date("Y/m/d H:i:s")));

    if(!is_null($modelPR)){

        if(isset($_POST['User'])){

            //Haces las validaciones y operaciones necesarios para guardar la nueva contraseña

            //Si todo sale bien, no olvides poner $modelPR->status=0; $modelPR->save(); para que no se puda usar otra vez la url

        }

        $this->render("changePassword",array('user'=>$modelPR->user));//user es la relación        

    }else{

        throw new CHttpException(404,'The specified page cannot be found.');

    }

}

  1. Debes crear la vista changePassword donde el usuario cambiará su contraseña que por lo menos debe contener 2 inputs para que el usuario ponga su contraseña y la confirme.

Hola,

del momento te digo MUCHAS GRACIAS.

Pronto como termine a trabajar, entento realizar lo que me dices.

Muchas Gracias otra vez a18327, y desculpa por mi espanol.