How to add hashed passwords in yii2

using Yii 2 basic Non-enhanced version.

I have a crud admin authentication system. In which only the identifier, username and password are stored in the database. When the user goes to login, if the username and password are correct, they are logged in.

However, now I want these passwords to be protected, so I want to salt them and hash them. This is the part that I find difficult to do, or, moreover, where to put things.

Part 1: I have an AdminController that matches my User Model Create.php page. Part 2: I have a siteController that comes with the LoginForm model and login.php page for login.

First I will look at the first part, since it will obviously have to generate a hashed password here.

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; } } 

Question ??: Thus, as you can see in this model, I only have the identifier, username and password coming from the database, so I take it, I will need to create one for the field in db with the name 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(); ?> 

That's right, so that was part 1, the actual bit in which the hashed password should be generated and stored in the database, how can I achieve this?

We are moving well along Part2:

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 (model):

 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> 

So, how do I integrate hashed_password for each user when I create it, and then check it at login?

I read this in the documentation, but just can't get it to work http://www.yiiframework.com/doc-2.0/guide-security-passwords.html

+8
php login yii hash yii2
source share
3 answers

When creating a user, you must generate and save a password hash. To generate it

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

To test it at login, change the user model that implements the UserIdentity function

  /** * 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); } 

Instead of the hash_password, use your db field.

+16
source share

just a reference to the user model of the Yii2 user template.

 /** * 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); } 

and then override the beforeSave method in the user model for the hash password before saving to DB

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

Today we just use the PHP cryptography function, instead we use password + salt hash algorithms, and this is more security than md5 (password + salt)

+4
source share

You do not need the password_hash field in the database. You can use the password field to save a hashed password so that it is more secure and difficult to crack a cracked password. Please modify the files as below,

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); } } 

Admin controller

 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, ]); } 

To reset the password, you need to send the reset password by email to the user.

0
source share

All Articles