2015-04-07 18 views
8

przy użyciu Yii 2 basic Nie wersja zaawansowana.sposób dodawania haseł w yii2

Mam system autoryzacji administratora crud. Który przechowuje tylko id, nazwę użytkownika i hasło w bazie danych. Kiedy użytkownik wchodzi do logowania, jeśli nazwa użytkownika i hasło są poprawne, są oni zalogowani.

Jednak teraz chcę, aby te hasła były bezpieczne, więc chcę je posolić i posypać. To jest ta część, którą ciężko jest mi znaleźć, lub więcej, gdzie umieścić rzeczy.

Część 1: Mam AdminController, który jest zgodny z moją stroną Modelu użytkownika Create.php. Część 2:. Mam SiteController która idzie w parze z modelem LoginForm i strony login.php się zalogować

pójdę nad częścią jednego pierwszego jak będzie oczywiście musiał rzeczywiście wygenerować hasło hashed tutaj.

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

Pytanie ??: Więc jak widać w tym modelu mam tylko id, nazwę użytkownika i hasło pochodzące z bazy danych, więc potrzebuję utworzyć dla pola w db nazwie "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(); ?> 

prawo tak, aby była częścią 1, rzeczywista nieco gdzie potrzebuje zakodowane hasło, aby być generowane i zapisywane w bazie danych, w jaki sposób można to osiągnąć?

OK poruszających się po Część 2:

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> 

A więc, w jaki sposób mogę zintegrować hash_hasło dla każdego użytkownika podczas jego tworzenia, a następnie sprawdzać po zalogowaniu?

Czytałem to w dokumentacji, ale po prostu nie mogę uzyskać to do pracy http://www.yiiframework.com/doc-2.0/guide-security-passwords.html

Odpowiedz

16

Podczas tworzenia użytkownika należy wygenerować i zapisać hash hasła. Aby wygenerować to

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

Aby sprawdzić go przy logowaniu, zmienić swój model użytkownika, który implementuje 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); 
    } 

Zamiast password_hash używać pole z db.

+0

gdzie umieszczam Yii :: $ app-> security-> generatePasswordHash ($ password); to jednak? –

+0

w twojej akcji stwórz: 'if ($ model-> load (\ Yii :: $ app-> request-> post()) && model-> register())' dzięki czemu w funkcji rejestru wygeneruj hash hasła i zapisz do db – ineersa

+0

dziękuję to działało, to po prostu, że w funkcji validatePassword nie wstawiłeś \ for yii: $ app .... więc nie działało, wtedy zdałem sobie sprawę, że była \ \ przed aplikacją yii :: $ ... podczas generowania zakotwiczone hasło. Dziękuję Ci! –

0

Nie musisz pole password_hash w bazie danych. Możesz użyć pola "hasło" do przechowywania zakodowanego hasła, aby było bezpieczniejsze i trudniejsze do złamania hasła.Proszę zmodyfikować pliki jak poniżej,

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

Aby zresetować hasło, należy wysłać link do resetowania hasła użytkownika .

+0

jak twoje hasło + sól jest lepsze od natywnego hasha? Język natywny zawsze jest inny, a dla PHP 5.5+ używa natywnego php password_hash i password_verify. to jest 2015 na zewnątrz, więc w którym punkcie użyć soli md5 +. – ineersa

+0

@ineersa: Właśnie pokazałem, jak utworzyć i zapisać hash_hasword w db. Do dewelopera należy używanie własnego wyboru hashu –

4

tylko referencja implementacji modelu użytkownika Yii2 z wyprzedzeniem.

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

następnie przesłanianie metody beforeSave w modelu użytkownika, aby przed hash hasła zapisywać do DB

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

Dziś po prostu zastosować funkcję krypty PHP zamiast wdrażania hasło + sól Hash algorytmy poczuć i it't większe bezpieczeństwo niż md5 (hasło + sól)

+0

ale nie używam zaawansowanego szablonu, więc model użytkownika jest całkowicie inny –

+0

czyli dodam metodę setPassword do Twojego modelu użytkownika – user776067