2015-04-07 5 views
8

mit Yii 2 Basis nicht die erweiterte Version hinzufügen.wie Sie Hash-Passwörter in yii2

Ich habe ein Crud-Admin-Authentifizierungssystem. Das speichert nur eine ID, einen Benutzernamen und ein Passwort in der Datenbank. Wenn der Benutzer sich anmeldet, wenn der Benutzername und das Passwort korrekt sind, sind sie eingeloggt.

Allerdings möchte ich jetzt diese Passwörter sichern, also möchte ich sie salzen und hacken. Dies ist der Teil, den ich schwer zu tun finde. Oder mehr, wo ich Dinge hinstellen kann.

Teil 1: Ich habe einen AdminController, der mit meiner User Model Create.php Seite einhergeht. Teil 2:. ich einen siteController habe, die zusammen mit dem Loginform Modell geht und die login.php Seite eingeloggt seine

Ich werde ersten Teil einen übergehen, da es offenbar tatsächlich haben wird, um ein Hash-Passwort zu generieren Hier.

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

Frage ??: So wie Sie in diesem Modell sehen kann ich nur id, Benutzername und Passwort haben kommend von der Datenbank, also nehme ich, muss ich einen für field in db namens "hashed_password" erstellen?

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(); ?> 

rechts, so dass Teil 1, die tatsächliche Bit war, wo die Hash-Passwort erzeugt werden muss, und in der Datenbank gespeichert, wie kann ich das erreichen?

Gut auf dem beweglichen 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 (Modell):

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> 

Also das ist es, wie integriere ich ein hashed_password für jeden Benutzer bei der Erstellung und validiere dies dann bei der Anmeldung?

Ich habe gelesen, dies auf die Dokumentation aber kann nicht nur erhalten diese http://www.yiiframework.com/doc-2.0/guide-security-passwords.html

Antwort

16

Wenn Sie einen Benutzer erstellen, sollten Sie einen Kennwort-Hash generieren und speichern. zu generieren es

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

es bei der Anmeldung zu überprüfen, Ihre Benutzer-Modell, das 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); 
    } 

Statt password_hash implementiert ändern Sie Ihr Feld von db verwenden.

+0

wo setze ich Yii :: $ app-> security-> generatePasswordHash ($ password); das obwohl? –

+0

in Ihrer Aktion create: 'if ($ model-> laden (\ Yii :: $ app-> request-> post()) && modell-> register())' so in diesem Register Funktion Passwort Hash generieren und speichern auf db – ineersa

+0

danke das hat funktioniert, es ist nur so, dass in der validatePassword Funktion du nicht \ für yii gesetzt hast: $ app .... so dass es nicht funktionierte, dann merkte ich, dass es ein \ vor yii :: $ app ... beim Generieren gab das Hash-Passwort Vielen Dank! –

0

Sie brauchen nicht ein password_hash Feld in der Datenbank zu arbeiten. Sie können das Feld "password" verwenden, um das Hash-Passwort zu speichern, sodass es sicherer und schwieriger ist, das Passwort zu knacken.Bitte ändern Sie die Dateien, wie unten,

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

das Passwort zurücksetzen, müssen Sie ein Passwort-Reset-Link, um dem Benutzer eine E-Mail .

+0

wie ist ihr passwort + salz besser als native hash? Native Hash ist immer anders, und für PHP 5.5+ verwendet es native PHP password_hash und password_verify. es ist 2015 draußen, also was md5 + salz zu verwenden. – ineersa

+0

@ineersa: Ich habe gerade gezeigt, wie Sie ein hashed_password in db erstellen und speichern. Es ist Sache des Entwicklers, seine eigene Hashing-Option zu verwenden. –

4

nur Referenz Yii2 Vorlage Benutzermodell implementieren.

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

dann zwingende before Methode in User-Modell Passwort Hash vor dem DB

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

Heute sparen wir Implementierung Passwort + Salz-Hash-Algorithmen youself nur statt PHP Krypta Funktion anwenden und it't mehr Sicherheit als md5 (passwort + salz)

+0

aber ich bin nicht mit der erweiterten Vorlage, so dass das Benutzermodell völlig anders ist –

+0

ich meine hinzufügen setPassword-Methode zu Ihrem Benutzermodell – user776067