簡體   English   中英

如何在Yii2中更新用戶配置文件期間管理密碼

[英]How to manage password during update user profile in Yii2

我可以成功添加用戶,For Password hashing我正在使用md5()但是當我更新用戶時它會給出錯誤。

以下是模型規則:

public function rules()
{
    return [
        [['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status'], 'required'],
        ['email','email'],
        [['confirm'], 'compare', 'compareAttribute' => 'password','on'=>'create'],
        [['firstname', 'lastname', 'username', 'email', 'password', 'confirm', ], 'string', 'max' => 255],
    ];
}

在窗體即視圖中,我使用以下代碼:

<div class="form-group">
<?php
    if($case == 'create') { //this condition called when create user 
        echo $form->field($model, 'password')->passwordInput([
            'maxlength' => true,
            'placeholder' => 'Enter the Password',
        ]);
    }
    else { // during update
        echo $form->field($model, 'password')->passwordInput([
            'maxlength' => true,
            'placeholder' => 'Enter the Password',
            'value' => '',
        ]);
    }
?>
</div>

<div class="form-group">
    <?= $form->field($model, 'confirm')->passwordInput([
        'maxlength' => true,
        'placeholder' => 'Confirm Password',
    ]) ?>   
</div>

在控制器中我使用以下代碼:

public function actionUpdate($id)
{
    $model = $this->findModel($id);
    $case = "update";
    if ($model->load(Yii::$app->request->post())) {
        $model->save();
        return $this->redirect(['view', 'id' => $model->id]);
    }
    else {
        return $this->render('update', [
            'model' => $model,
            'all_users_array' => $all_users_array,
            'all_groups_array' => $all_groups_array,
            'case' => $case,
        ]);
    }
}

我收到錯誤:

未定義的偏移量:1無法准備SQL:UPDATE xbox_user SET password =:qp0, role =:qp1, modified =:qp2, status =:qp3 WHERE id =:qp4

任何人都可以讓我在那里修改哪些代碼?

謝謝!

用戶模型

public function rules()
{
    return [
        [['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status'], 'required'],
        ['email','email'],
        [['password', 'confirm'], 'required', 'on' => 'create'],

        ['confirm', 'compare', 'compareAttribute' => 'password', 'message'=>"Passwords does not match." ],
        [['firstname', 'lastname', 'username', 'email', 'password', 'confirm', ], 'string', 'max' => 255],
    ];
}

更新行動

public function actionUpdate($id)
{
    $model = $this->findModel($id);
    $model->passowrd = '';
    $model->confirm = '';

    if ($model->load(Yii::$app->request->post())) {
        $model->role = $model->role[0]; 
        if (empty($model->password) || empty($model->confirm)) {
            $model->password = $model->getOldAttribute('password');
            $model->confirm = $model->getOldAttribute('confirm');
        }
        if ($model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        }
    } else {
        return $this->render('update', [
            'model' => $model,
            'all_users_array'=>$all_users_array,
            'all_groups_array'=>$all_groups_array,
        ]);
    }
}

形成

<div class="form-group">
    <?= $form->field($model, 'password')->passwordInput(['maxlength' => true,'placeholder'=>'Enter the Password']) ?>
</div>
<div class="form-group">
    <?= $form->field($model, 'confirm')->passwordInput(['maxlength' => true,'placeholder'=>'Confirm Password']) ?>   
</div>

最好在你的情況下使用scenarios並使用rules()來滿足其他需求,在Users.php模型文件中編寫以下代碼:

public function scenarios(){
  $scenarios = parent::scenarios();
  $scenarios['create'] = ['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status', 'password','confirm'];
  $scenarios['update'] = ['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status'];
  return $scenarios;
}

/**
 * @inheritdoc
 */
public function rules()
{
    return [
        [['firstname', 'lastname', 'username', 'email', 'role', 'group_user','status', 'password','confirm'], 'required'],
        ['email', 'filter', 'filter' => 'trim'],
        ['email', 'unique' ],
        ['email', 'unique' ,'targetAttribute' => 'email'],
        ['email', 'required'],
        ['email', 'email'],
        ['email', 'unique', 'targetClass' => '\common\models\Users', 'message' => 'This email address has already been taken.'],
        ['confirm', 'compare', 'compareAttribute'=>'password', 'message'=>"Passwords does not match." ],
        [['firstname', 'lastname', 'username', 'email', 'password', 'confirm', ], 'string', 'max' => 255],
    ];
}

在您的視圖文件中使用以下代碼:

<div class="form-group">
 <?php
  if($case == 'create'){
    echo $form->field($model, 'password')->passwordInput(['maxlength' => true,'placeholder'=>'Enter the Password']);
  }
  else{
    echo $form->field($model, 'password')->passwordInput(['maxlength' => true,'placeholder'=>'Enter the Password']);
 }
?>   
</div>
<div class="form-group">
    <?= $form->field($model, 'confirm')->passwordInput(['maxlength' =>true,'placeholder'=>'Confirm Password']) ?>   
 </div>

在您的控制器文件中, UsersController.php使用以下代碼:

public function actionUpdate($id)
{
  $model = $this->findModel($id);

  $model->scenario = 'update'; // calling scenario of update
  if ($model->load(Yii::$app->request->post())) {

        $req_array = yii::$app->request->post();
        $role  = $req_array['Users']['role'][0];

        $model->role = $role;
        if($req_array['Users']['password'] !== $req_array['Users']['confirm'])
        {
          $model->addError('confirm','Password and Confirm should be same.');
          $model->password = $req_array['Users']['password'];
          $model->confirm = $req_array['Users']['confirm'];
          return $this->render('update', [
              'model' => $model,
              'all_users_array'=>$all_users_array,
              'all_groups_array'=>$all_groups_array,
              'case'=>$case,
          ]);
        }
        elseif( ($req_array['Users']['password'] == $req_array['Users']['confirm']) && (!empty($req_array['Users']['password'])))
        {
          $model->password = MD5($req_array['Users']['password']);
          $model->save();
          return $this->redirect(['view', 'id' => $model->id]);
        }
        else
        {

          $model->save();
          return $this->redirect(['view', 'id' => $model->id]);
        }
      } else {
          $model->password = '';
          return $this->render('update', [
              'model' => $model,
              'all_users_array'=>$all_users_array,
              'all_groups_array'=>$all_groups_array,
              'case'=>$case,
          ]);
      }
    }

使用此代碼,您將不會在更新中收到所需密碼的錯誤。如果您填寫密碼,則將運行確認密碼和所需密碼的過程。 希望這對你有所幫助。

我有自己的基本用戶模型,我可以重用於大多數項目,如果更新表單沒有提供密碼,它會處理更新新密碼或保留前一個密碼。 還實現IdentityInterface以便它可以用於登錄到Application。

我的基本用戶模型:

<?php

namespace app\models;

use Yii;
use yii\db\ActiveRecord;
use yii\web\IdentityInterface;

class User extends ActiveRecord implements IdentityInterface {
    const SCENARIO_LOGIN = 'login';
    const SCENARIO_CREATE = 'create';
    const SCENARIO_UPDATE = 'update';

    // We use $hash to save the hashed password we already have saved in the DB
    public $hash;
    public $password_repeat;

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return 'user';
    }

    /**
     * @inheritdoc
     */
    public function scenarios() {
        $scenarios = parent::scenarios();
        $scenarios[self::SCENARIO_LOGIN] = ['user', 'password'];
        $scenarios[self::SCENARIO_CREATE] = ['user', 'password', 'password_repeat', 'email', 'authKey'];
        $scenarios[self::SCENARIO_UPDATE] = ['user', 'password', 'password_repeat', 'email'];
        return $scenarios;
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['user'], 'string', 'max' => 45],

            [['email'], 'string', 'max' => 45],
            [['email'], 'email'],

            [['password', 'password_repeat'], 'string', 'max' => 60],

            [['authKey'], 'string', 'max' => 32],

            [['user', 'password'], 'required', 'on' => self::SCENARIO_LOGIN],
            [['user', 'password', 'password_repeat', 'email'], 'required', 'on' => self::SCENARIO_CREATE],
            [['user', 'email'], 'required', 'on' => self::SCENARIO_UPDATE],

            // Generate a random String with 32 characters to use as AuthKey
            [['authKey'], 'default', 'on' => self::SCENARIO_CREATE, 'value' => Yii::$app->getSecurity()->generateRandomString()],

            [['password'], 'compare', 'on' => self::SCENARIO_CREATE, 'skipOnEmpty' => true],

            [['user'], 'unique'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => 'Id',
            'user' => 'User',
            'password' => 'Password',
            'authKey' => 'AuthKey',
            'email' => 'Email',
        ];
    }

    /**
     * @inheritdoc
     */
    public function beforeSave($insert) {
        if (parent::beforeSave($insert)) {
            if($insert) {
                $this->password = Yii::$app->getSecurity()->generatePasswordHash($this->password);
            }
            else {
                if(strlen($this->password) > 0) {
                    $this->password = Yii::$app->getSecurity()->generatePasswordHash($this->password);
                }
                else {
                    $this->password = $this->hash;
                }
            }
            return true;
        }
        return false;
    }

    /**
     * @inheritdoc
     */
    public function afterFind() {
        $this->hash = $this->password;
        $this->password = '';
        parent::afterFind();
    }

    /**
     * @inheritdoc
     */
    public static function findIdentity($id) {
        return self::findOne($id);
    }

    /**
     * @inheritdoc
     */
    public static function findIdentityByAccessToken($token, $type = null) {
        throw new NotSupportedException('"findIdentityByAccessToken" is not implemented.');
    }

    /**
     * @inheritdoc
     */
    public static function findByUsername($username) {
        $model = static::findOne(['user' => $username]);
        return $model;
    }

    /**
     * @inheritdoc
     */
    public function getId() {
        return $this->getPrimaryKey();
    }

    /**
     * @inheritdoc
     */
    public function getAuthKey() {
        return $this->authKey;
    }

    /**
     * @inheritdoc
     */
    public function validateAuthKey($authKey) {
        return $this->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 Yii::$app->getSecurity()->validatePassword($password, $this->hash);
    }
}

這樣,您只需在createupdatelogin操作中使用相應的scenario

$model->scenario = User::SCENARIO_LOGIN;
$model->scenario = User::SCENARIO_CREATE;
$model->scenario = User::SCENARIO_UPDATE;

首先嘗試這個

[['confirm'], 'compare', 'compareAttribute' => 'password','on'=>'create']

如果不行,那么請按照以下步驟創建您的更新方案,不要比較密碼您是否嘗試過方案..我將給出一個用戶注冊和用戶登錄的簡單示例我希望它能幫助您

<?php
class User extends Model
{
    public $name;
    public $email;
    public $password;
    public function rules(){
        return [
            [['name','email','password'],'required'],
            ['email','email'],
            [['name', 'email', 'password'], 'required', 'on' => 'register'],
            ];
    }
    public function scenarios()
    {
        $scenarios = parent::scenarios();
        $scenarios['login'] = ['name','password'];//Scenario Values Only Accepted
        return $scenarios;
    }
}
?>

應用場景模型請參閱下面的代碼,我們添加了兩種設置模型場景的方法。 默認情況下,方案將支持模型規則。

<?php
class UserController extends Controller
{
    // APPLY SCENARIOS
    // scenario is set as a property
    public function  actionLogin(){
        $model = new User;
        $model->scenario = 'login';
    }
    // scenario is set through configuration
    public function  actionRegister(){
        $model = new User(['scenario' => 'register']);
    }
}
?>

在此輸入圖像描述 在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM