2015-04-07 21 views
8

utilizzando Yii 2 basic Non la versione avanzata.come aggiungere password hash in yii2

Ho un sistema di autenticazione amministratore crud. Che memorizza solo un ID, nome utente e password nel database. Quando l'utente accede al log in se il nome utente e la password sono corretti sono loggati.

Tuttavia ora voglio rendere sicure queste password, quindi voglio saltarle e cancellarle. Questa è la parte che sto trovando difficile da fare, o ancora di più dove mettere le cose.

Parte 1: Ho un AdminController che accompagna la pagina Crea.php del modello utente. Parte 2:. Ho un siteController che va di pari passo con il modello LoginForm e la pagina login.php effettuare il login

voglio andare oltre la prima parte prima come sarà ovviamente necessario generare in realtà una password hash Qui.

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

Domanda ??: Così come si può vedere in questo modello ho solo id, username e password provenendo dal database, quindi prendo dovrò crearne uno per campo in db chiamato "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(); ?> 

Proprio così che era parte 1, il bit effettivo in cui l'hash della password deve essere generato e salvato nel database, come posso raggiungere questo obiettivo?

movimento Ok sul 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 (modello):

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> 

Quindi, come faccio a integrare una password hashed per ogni utente quando creano e quindi convalidarlo al momento dell'accesso?

Ho letto questo sul documentazione, ma appena cant farlo funzionare http://www.yiiframework.com/doc-2.0/guide-security-passwords.html

risposta

16

Quando si crea un utente, è necessario generare e salvare l'hash della password. per generarlo

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

Per controllare sul login, modificare il proprio modello d'uso che 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); 
    } 

Invece di password_hash utilizzare il campo da db.

+0

dove inserire Yii :: $ app-> security-> generatePasswordHash ($ password); questo però? –

+0

nella tua azione create: 'if ($ model-> load (\ Yii :: $ app-> request-> post()) && model-> register())' così in quella funzione register genera hash password e salva in db – ineersa

+0

grazie a questo ha funzionato, solo che nella funzione validatePassword non hai inserito \ per yii: $ app .... quindi non funzionava, quindi ho realizzato che esisteva \ prima di yii :: $ app ... durante la generazione la password hash. Grazie! –

0

Non hai bisogno di un campo password_hash nel database. È possibile utilizzare il campo "password" per memorizzare la password con hash in modo che sia più sicura e difficile da intrufolare per decifrare la password.Si prega di modificare i file come sotto,

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

controller Admin

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

per reimpostare la password, è necessario e-mail un link di reimpostazione della password per l'utente .

+0

come è la password + sale meglio dell'hash nativo? L'hash nativo è sempre diverso, e per php 5.5+ usa nativo php password_hash e password_verify. è il 2015 fuori, quindi a che punto usare md5 + salt. – ineersa

+0

@ineersa: ti ho appena mostrato come creare e memorizzare una hashed_password in db. Spetta allo sviluppatore utilizzare la propria scelta di hashing –

4

è sufficiente fare riferimento all'implementazione del modello utente modello di anticipo 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); 
} 

poi override metodo BeforeSave nel modello di utente per hash della password prima di salvare a DB

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

Oggi basta applicare la funzione PHP cripta invece implementare algoritmi di hash di password + sale portarvi direttamente, e it't più sicurezza di md5 (password + sale)

+0

ma non utilizzo il modello avanzato in modo che il modello utente sia completamente diverso –

+0

intendo aggiungere il metodo setPassword al modello utente – user776067

Problemi correlati