パスワードフィールドを更新したくない。これを使用する方法。パスワードにmd5エンコードを使用している。したがって、yiiフレームワークのパスワードフィールドを更新したくない。
6 に答える
この場合、シナリオを使用しない方がよいと思います。ルールの次のコードは、シナリオを示しています。次のフィールドは必須です。しかし、そうではありません:他をスキップします。
array('name, username, email', 'required', 'on' => 'update'),
たとえば、パスワードの長さを32文字までに制限しているが、データベースにsha1(長さ40)の形式で格納されている場合、バリデーターがデータベースクエリをブロックするため、問題が発生します。更新を行うと、「validatе」メソッドは、postによって配信された新しいプロパティだけでなく、すべてのクラスプロパティ(データベーステーブルのマッピングに関して)をチェックします。
メソッド「saveAttributes」を使用できますが、別の問題に気づきました。「email」列がデータベース内で一意であり、編集された電子メールが既存の1つと重複している場合、ルールで定義されているYiiメッセージシステムは通知できず、データベースクエリに関するエラーコードをスローします。
私が考える最も簡単なアプローチは、この場合はシナリオを設定しないことです。必要なプロパティを引数として送信するだけです。これにより、GIIによって作成されたすべてのCRUD機能が保持されます。
コードでは次のようになります:(モデル内)
public function rules() {
return array(
array('name, username, email, password', 'required'),
);
}
(コントローラー内)
if($id==Yii::app()->user->id){
$model=$this->loadModel($id);
if(isset($_POST['JbJsJobResume'])) {
$model->attributes=$_POST['JbJsJobResume'];
if($model->save(true, array('name', 'username', 'email')))
$this->redirect(array('view','id'=>$model->id));
}
$this->render('update',array( 'model'=>$model, ));
}
RBACを使用していないことに気づきました。とても便利で柔軟性があります。ぜひお試しください。
http://www.yiiframework.com/doc/guide/1.1/en/topics.auth#role-based-access-control
モデルでは、次のようなことを行う必要があります。
public function rules() {
return array(
array('name, username, email, password', 'required', 'on' => 'create'),
array('name, username, email', 'required', 'on' => 'update'),
);
}
現在実行しているシナリオが更新であるとしましょう。だから私はそこにパスワードを必要としません。私はあなたが持っているかもしれない作成シナリオでのみそれを必要とします。したがって、あなたが持っているビューファイルでパスワードフィールドを削除し、あなたが持っているアクションの中にこれを含めます:
$model->setScenario('update');
したがって、パスワードは不要で、同じままです。
パスワードの変更については、新しいアクション(actionPassChangeなど)を作成できます。このアクションでは、新しいパスワードを2回入力する必要があります。
$model->attributes=$_POST['JbJsJobResume'];
すべての属性を割り当てる代わりに、保存したい属性だけを次のように割り当てます。
$model->name=$_POST['JbJsJobResume']['name'];
$model->save();
最初のオプション設定する前に、パスワードフィールドの設定を解除するだけです。
function update(){
$model=$this->loadModel($id);
unset($_POST['JbJsJobResume']['password']);
$model->attributes=$_POST['JbJsJobResume'];
$model->save();
}
2番目のオプション:一時変数を使用します:
function update(){
$model=$this->loadModel($id);
$temPassword = $model->passwrod;
$model->attributes=$_POST['JbJsJobResume'];
$model->passwrod = $temPassword;
$model->save();
}
3番目のオプション:シナリオを使用する
なぜこれが問題になるのかわかりません。コードによっては、その理由を理解するのに役立つ場合があります。パスワードを取得/更新したくない場合は、フォームのパスワードフィールドがなぜですか?
ビューからパスワードフィールドを削除すると、パスワードフィールドの値はコントローラーにポストバックされず、更新されません。
上記の方法が機能しない可能性があります。これは、ユーザーモデルで、afterValidate
方法でパスワードを暗号化している可能性がありますか?:
protected function afterValidate()
{
parent::afterValidate();
$this->password = $this->encrypt($this->password);
}
public function encrypt($value)
{
return md5($value);
}
このシナリオでは、ビューからパスワードフィールドを削除し、名前、ユーザー名、または電子メールを更新するだけで、パスワードのmd5ハッシュが自動的に再ハッシュされ、実際のパスワードが失われます。
これを回避する1つの方法は、afterValidateメソッド(作成または更新)でパスワードをmd5することですが、ユーザーが同じフォームでプロファイルの詳細を変更したい場合は、パスワードをもう一度確認するようにユーザーに依頼してください。
- フォーム:ユーザーが名前を変更し、パスワードを確認します
- 投稿されたフォーム
- コントローラが認証メソッドを呼び出します。
- trueの場合、ユーザーテーブルのエントリを上書きします(検証済みのpwを含む)
@Gravyの答えは正しいと思います。GravyとNikosTsirakisに感謝します。@faizphpとほぼ同じ問題を修正しました。Nikos Tsirakisが言ったように、ユーザーモデルのシナリオを追加しましたが、同じ問題が発生しました。次に、User.afterValidateでパスワードを暗号化することがわかりました。そのため、ユーザーモデルを毎回更新すると、プログラムはデータベース内のパスワードを間違ったパスワードに再度暗号化します。だから私は私の機能をから変更しました
protected function afterValidate()
{
parent::afterValidate();
if (!$this->hasErrors())
$this->password = $this->hashPassword($this->password);
}
</code>
に
protected function afterValidate()
{
parent::afterValidate();
if (!$this->hasErrors() && $this->scenario==="create")
$this->password = $this->hashPassword($this->password);
}
。うまくいくようです。