@Ace_Viral

Как сгенерировать безопасный хэш в yii2?

В модели User.php перед сохранением модели я прописываю:
public function beforeSave($insert)
    {
        // Хэширование паролей А3
        if ($this->password) {
            $this->password_hash = Yii::$app->security->generatePasswordHash($this->password);
        }
        // Хэширование рефреш токена
        if ($this->refresh_token) {
            $this->refresh_token_hash = Yii::$app->security->generatePasswordHash($this->refresh_token);
        }

        return parent::beforeSave($insert);
    }


С паролем проблем нету эта функция отрабатывает правильно:
Yii::$app->security->validatePassword($password, $user->password_hash)

Но вот с refresh_token'ом есть проблемы как выяснилось когда значения очень длинное, то после определенного момента он всегда выводит true.
public function actionRefresh()
     {
          $refresh_token = Yii::$app->request->headers->get('Authorization');
          $refresh_token = substr($refresh_token, 7);

          $decoded = User::getUserDataFromJWT($refresh_token);

          $user = User::find()
               ->where(['id' => $decoded->data->user_id])
               ->one();

          if ($user) {
               if (Yii::$app->security->validatePassword($refresh_token, $user->refresh_token_hash)) {
                          ..........

И мне нужно что то придумать как безопасно хранить refresh_toke_hash в базе данных и при этом без проблем его валидировать и проверять правильность.
Помогите пожалуйста
  • Вопрос задан
  • 403 просмотра
Пригласить эксперта
Ответы на вопрос 1
OrlovEvgenii
@OrlovEvgenii
golang developer / DevOps
можно использовать функцию generateRandomString() из компонента security. Эта функция создает случайную строку указанной длины, которую можно использовать как соль для хеша

public function beforeSave($insert)
{
    if ($this->isNewRecord || $this->isAttributeChanged('password')) {
        $this->password_hash = Yii::$app->security->generatePasswordHash($this->password);
    }
    
    if ($this->isNewRecord || $this->isAttributeChanged('refresh_token')) {
        $salt = Yii::$app->security->generateRandomString();
        $this->refresh_token_salt = $salt;
        $this->refresh_token_hash = Yii::$app->security->generatePasswordHash($this->refresh_token . $salt);
    }

    return parent::beforeSave($insert);
}


А в методе actionRefresh вы можете использовать эту соль, чтобы проверить правильность refresh_token:

public function actionRefresh()
{
    $refresh_token = Yii::$app->request->headers->get('Authorization');
    $refresh_token = substr($refresh_token, 7);

    $decoded = User::getUserDataFromJWT($refresh_token);

    $user = User::find()
        ->where(['id' => $decoded->data->user_id])
        ->one();

    if ($user && $user->refresh_token_salt) {
        $refresh_token_hash = Yii::$app->security->generatePasswordHash($refresh_token . $user->refresh_token_salt);
        if (Yii::$app->security->validatePassword($refresh_token_hash, $user->refresh_token_hash)) {
            // Refresh token is valid
        }
    }
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы