seguridad password generate encriptar contraseña php yii hash login yii2

php - password - cómo agregar contraseñas hash en yii2



security yii2 (3)

usando Yii 2 basic No es la versión avanzada.

Tengo un sistema de autenticación crud admin. Que almacena solo una identificación, nombre de usuario y contraseña en la base de datos. Cuando el usuario va a iniciar sesión si el nombre de usuario y la contraseña son correctos, está conectado.

Sin embargo, ahora quiero hacer que estas contraseñas sean seguras, así que quiero sacarlas y usarlas. Esta es la parte que me resulta difícil de hacer. O más, dónde poner las cosas.

Parte 1: Tengo un AdminController que va junto con mi página User Model Create.php. Parte 2: tengo un SiteController que va junto con el modelo de LoginForm y la página login.php para iniciar sesión.

Revisaré la primera parte, ya que obviamente tendrá que generar una contraseña hash aquí.

AdminController:

public function actionCreate() { $model = new User(); if ($model->load(Yii::$app->request->post()) && $model->save()) { return $this->redirect([''view'', ''id'' => $model->id]); } else { return $this->render(''create'', [ ''model'' => $model, ]); } }

User.php

<?php namespace app/models; use yii/base/NotSupportedException; use yii/db/ActiveRecord; use yii/web/IdentityInterface; use yii/data/ActiveDataProvider; /** * User model * * @property integer $id * @property string $username * @property string $password */ class User extends ActiveRecord implements IdentityInterface { /** * @inheritdoc */ public static function tableName() { return ''Users''; } public function rules(){ return [ [[''username'',''password''], ''required''] ]; } public static function findAdmins(){ $query = self::find(); $dataProvider = new ActiveDataProvider([ ''query'' => $query, ]); return $dataProvider; } /** * @inheritdoc */ public static function findIdentity($id) { return static::findOne([''id'' => $id]); } /** * @inheritdoc */ public static function findIdentityByAccessToken($token, $type = null) { throw new NotSupportedException(''"findIdentityByAccessToken" is not implemented.''); } /** * Finds user by username * * @param string $username * @return static|null */ public static function findByUsername($username) { return static::findOne([''username'' => $username]); } /** * @inheritdoc */ public function getId() { return $this->id; } /** * @inheritdoc */ public function getAuthKey() { return static::findOne(''AuthKey''); } /** * @inheritdoc */ public function validateAuthKey($authKey) { return static::findOne([''AuthKey'' => $authKey]); } /** * Validates password * * @param string $password password to validate * @return boolean if password provided is valid for current user */ public function validatePassword($password) { return $this->password === $password; } }

Pregunta: Entonces, como pueden ver en este modelo, solo tengo el id, el nombre de usuario y la contraseña provenientes de la base de datos, así que tendré que crear uno para el campo en db llamado "hashed_password"?

create.php:

<?php $form = ActiveForm::begin(); ?> <?= $form->field($model, ''username'')->textInput([''maxlength'' => 50]) ?> <?= $form->field($model, ''password'')->passwordInput([''maxlength'' => 50]) ?> <div class="form-group"> <?= Html::submitButton($model->isNewRecord ? ''Create'' : ''Update'', [''class'' => $model->isNewRecord ? ''btn btn-success'' : ''btn btn-primary'']) ?> </div> <?php ActiveForm::end(); ?>

Correcto para que fuera la parte 1, el bit real donde la contraseña hash necesita ser generada y guardada en la base de datos, ¿cómo puedo lograr esto?

Bien moviéndose en la Parte2:

SiteController:

public function actionLogin() { if (!/Yii::$app->user->isGuest) { return $this->goHome(); } $model = new LoginForm(); if ($model->load(Yii::$app->request->post()) && $model->login()) { return $this->goBack(); } else { return $this->render(''login'', [ ''model'' => $model, ]); } }

LoginForm.php (modelo):

class LoginForm extends Model { public $username; public $password; public $rememberMe = true; private $_user = false; /** * @return array the validation rules. */ public function rules() { return [ // username and password are both required [[''username'', ''password''], ''required''], // rememberMe must be a boolean value [''rememberMe'', ''boolean''], // password is validated by validatePassword() [''password'', ''validatePassword''], ]; } /** * Validates the password. * This method serves as the inline validation for password. * * @param string $attribute the attribute currently being validated * @param array $params the additional name-value pairs given in the rule */ public function validatePassword($attribute, $params) { if (!$this->hasErrors()) { $user = $this->getUser(); if (!$user || !$user->validatePassword($this->password)) { $this->addError($attribute, ''Incorrect username or password.''); } } } /** * Logs in a user using the provided username and password. * @return boolean whether the user is logged in successfully */ public function login() { if ($this->validate()) { return Yii::$app->user->login($this->getUser(), $this->rememberMe ? 3600*24*30 : 0); } else { return false; } } /** * Finds user by [[username]] * * @return User|null */ public function getUser() { if ($this->_user === false) { $this->_user = User::findByUsername($this->username); } return $this->_user; } }

Login.php:

<?php $form = ActiveForm::begin(); ?> <?= $form->field($model, ''username''); ?> <?= $form->field($model, ''password'')->passwordInput(); ?> <div class="form-group"> <div class="col-lg-offset-1 col-lg-11"> <?= Html::submitButton(''Login'', [''class'' => ''btn btn-primary'', ''name'' => ''login-button'']) ?> </div> </div>

Entonces eso es todo, ¿cómo puedo integrar una contraseña hashed para cada usuario cuando crean y luego validar esto al iniciar sesión?

He estado leyendo esto en la documentación pero simplemente no puedo hacer que esto funcione http://www.yiiframework.com/doc-2.0/guide-security-passwords.html


Cuando crea un usuario, debe generar y guardar el hash de contraseña. Para generarlo

/Yii::$app->security->generatePasswordHash($password);

Para verificarlo al iniciar sesión, cambie su modelo de usuario que implementa UserIdentity

/** * Validates password * * @param string $password password to validate * @return boolean if password provided is valid for current user */ public function validatePassword($password) { return Yii::$app->getSecurity()->validatePassword($password, $this->password_hash); }

En lugar de password_hash usa tu campo de db.


No necesita un campo password_hash en la base de datos. Puede utilizar el campo "contraseña" para almacenar la contraseña hash para que sea más seguro y difícil de intrusión para descifrar la contraseña. Por favor, modifique los archivos como a continuación,

User.php

<?php namespace app/models; use yii/base/NotSupportedException; use yii/db/ActiveRecord; use yii/web/IdentityInterface; use yii/data/ActiveDataProvider; class User extends ActiveRecord implements IdentityInterface { public $salt = "stev37f"; //Enter your salt here public static function tableName() { return ''Users''; } public function rules() { return [ [[''username'',''password''], ''required''] ]; } public static function findAdmins() { $query = self::find(); $dataProvider = new ActiveDataProvider([ ''query'' => $query, ]); return $dataProvider; } public static function findIdentity($id) { return static::findOne([''id'' => $id]); } public static function findIdentityByAccessToken($token, $type = null) { throw new NotSupportedException(''"findIdentityByAccessToken" is not implemented.''); } public static function findByUsername($username) { return static::findOne([''username'' => $username]); } public function getId() { return $this->id; } public function getAuthKey() { return static::findOne(''AuthKey''); } public function validateAuthKey($authKey) { return static::findOne([''AuthKey'' => $authKey]); } public function validatePassword($password) { return $this->password === static::hashPassword($password); //Check the hashed password with the password entered by user } public static function hashPassword($password) {// Function to create password hash return md5($password.$this->salt); } }

Controlador de administrador

public function actionCreate() { $model = new User(); if ($model->load(Yii::$app->request->post()) && $model->validate()) { $model->password = User::hashPassword($model->password); // Hash the password before you save it. if($model->save()) return $this->redirect([''view'', ''id'' => $model->id]); } return $this->render(''create'', [ ''model'' => $model, ]); }

Para restablecer la contraseña, debe enviar un correo electrónico al usuario para restablecer la contraseña.


simplemente haga referencia al implemento del modelo de usuario de plantilla de avance Yii2.

/** * Generates password hash from password and sets it to the model * * @param string $password */ public function setPassword($password) { $this->password_hash = Yii::$app->security->generatePasswordHash($password); }

luego reemplazando el método beforeSave en el modelo de usuario por la contraseña hash antes de guardar en DB

public function beforeSave($insert) { if(parent::beforeSave($insert)){ $this->password_hash=$this->setPassword($this->password_hash); return true; }else{ return false; } }

Hoy solo aplicamos la función cripta de PHP en lugar de implementar la contraseña + algoritmos de sal de hash youself, y es más seguridad que md5 (contraseña + sal)