비밀번호 암호화 시 발생하는 문제
오늘 저는 비밀번호 md5 암호화 문제에 직면했습니다. 당시 저는 "thinkphp5.0.9-> Model-> "Data Completion"은 자동 암호화를 구현하는데, 위의 "thinkphp5.0.9->Model->Modifier"에서는 modifier가 데이터 완성과 동일한 기능을 가지고 있는 것으로 확인됩니다.
//模型层 class User extends Model{ //$auto包含新增$insert和更新操作$update,就是不管新增还是更新我就自动执行 protected $auto = ['password','create']; public function setPasswordAttr($value) { return md5($value); } public function setCreateAttr() { return time(); } //注册用户 public function register($data){ $bool = $this->save($data); return $bool ? $this->id : 0; } } //控制器层方法 public function register() { if(request()->isAjax()){ $userModel=new \app\index\Model\User(); $data=input('post.'); //注册 $res = $userModel->register($data); echo $res; }else{ $this->error('非法访问'); } }
로그인 후 복사
"wwwwww"를 입력하고 위의 코드에 따라 등록한 결과 비밀번호 암호화 결과는 b8d3c8f4db0c248ac242dd6e098bbf85올바른 암호화 결과입니다. 는 d785c99d298a4e9e6e13fe99e602ef42 인데, 이때는 눈치 채지 못하셨을 수도 있겠지만, 로그인 시에는 로그인이 되지 않습니다. 예를 들어 비밀번호는 여전히 wwwwww 입니다. 로그인하시면 암호화 오류가 있다고 의심하실 수 있습니다. 그러면 "setPasswordAttr( of data 완성)" )"이 나옵니다.
꺼내고 따로 테스트해 보세요
직접 알려드리겠습니다. 수식어와 데이터를 여러 번 수정하고 2시간 동안 테스트를 완료한 결과 마침내 새로운 테스트 테이블을 생성하고
//新建test模型层 namespace app\index\Model; use think\Model; class Test extends Model { protected $auto = ['password']; protected function setPasswordAttr($value) { dump(md5(NULL)); dump($value); dump(md5($value)); return md5($value); } public function addPass(){ echo "修改器"; $this->password='wwwwww'; dump($this->password); echo "数据完成"; $this->save([ 'username' => 'thinkphp', 'password' => 'wwwwww', 'create' => '123456' ]); } } //控制器中添加test方法 public function test(){ $user = model('Test'); //调用model层函数 $user->addPass(); }
로그인 후 복사
수식어를 별도로 테스트했습니다.
먼저 "데이터 완성" 부분을 주석 처리해 주세요. 모델 레이어
namespace app\index\Model; use think\Model; class Test extends Model { protected $auto = ['password']; protected function setPasswordAttr($value) { dump(md5(NULL));//把NULL加密 dump($value); //查看调用时传递过来的值 dump(md5($value));//把该值加密 return md5($value);//把该值加密返回 } public function addPass(){ echo "修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理"; $this->password='wwwwww'; dump($this->password);//输出返回后的结果 // echo "数据完成:在数据字段insert,update,auto时进行处理"; // $this->save([ // 'username' => 'thinkphp', // 'password' => 'wwwwww', // 'create' => '123456' // ]); } }
로그인 후 복사
실행 후 페이지에 결과가 표시되며, 값을 할당할 때 수정자가 자동으로 암호화되는 것으로 나타났습니다. 현재는 데이터베이스에 저장되지 않습니다.
修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理 string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密的NULL】 string(6) "wwwwww"【传过来的$value】 string(32) "d785c99d298a4e9e6e13fe99e602ef42"【加密$value】 string(32) "d785c99d298a4e9e6e13fe99e602ef42"【return返回的结果】
로그인 후 복사
데이터 완성 테스트
"수식자" 부분의 코드를 주석 처리하고 데이터 완성만 실행
namespace app\index\Model; use think\Model; class Test extends Model { protected $auto = ['password']; protected function setPasswordAttr($value) { dump(md5(NULL));//把NULL加密 dump($value); //查看调用时传递过来的值 dump(md5($value));//把该值加密 return md5($value);//把该值加密返回 } public function addPass(){ // echo "修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理"; // $this->password='wwwwww'; // dump($this->password);//输出返回后的结果 echo "数据完成:在数据字段insert,update,auto时进行处理"; $this->save([ 'username' => 'thinkphp', 'password' => 'wwwwww', 'create' => '123456' ]); } }
로그인 후 복사
이유 찾기
실행 후 setPasswordAttr()이 두 번 실행된 것으로 확인되어 비밀번호는
数据完成:在数据字段insert,update,auto时进行处理 string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】 string(6) "wwwwww"【传入的$value】 string(32) "d785c99d298a4e9e6e13fe99e602ef42"【加密$value="wwwwww"】 string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】 string(32) "d785c99d298a4e9e6e13fe99e602ef42"【传入的$value】 string(32) "b8d3c8f4db0c248ac242dd6e098bbf85"【再次加密$value="d785c99...f42"】
로그인 후 복사
두 번 암호화하는 이유는 값을 지정할 때 한 번, $auto가 자동으로 완료될 때 한 번 암호화되기 때문입니다
[ 'username' => 'thinkphp', 'password' => 'wwwwww', 'create' => '123456' ]
로그인 후 복사
초기 문제를 해결하세요
한 번 암호화하려면 $auto만 보호하세요. = ['password']; 주석 처리하거나 로그인 코드에서 md5(md5("wwwwww"))를 수행하고 주석 처리한 후 다음을 실행합니다.
数据完成:在数据字段insert,update,auto时进行处理 string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】 string(6) "wwwwww"【$value】 string(32) "d785c99d298a4e9e6e13fe99e602ef42"【加密结果】
로그인 후 복사
여러 필드가 보호되는 경우 $auto = ['password ','create']; 보호된 $auto = ['create']; 비밀번호를 제거하면 원래 문제가 해결됩니다.
데이터만 완성되고 값이 할당되지 않은 경우
위에서 내가 항상 NULL을 암호화하는 방법을 보셨을 것입니다. protected $auto = ['password'];가 자동 완성을 정의하는 또 다른 상황이 있습니다. 할당:
namespace app\index\Model; use think\Model; class Test extends Model { protected $auto = ['password']; protected function setPasswordAttr($value) { dump(md5(NULL));//把NULL加密 dump($value); //查看调用时传递过来的值 dump(md5($value));//把该值加密 return md5($value);//把该值加密返回 } public function addPass(){ // echo "修改器:修改器的作用是可以在数据赋值的时候自动进行转换处理"; // $this->password='wwwwww'; // dump($this->password);//输出返回后的结果 echo "数据完成:在数据字段insert,update,auto时进行处理"; $this->save([ 'username' => 'thinkphp', //注释掉,不赋值 // 'password' => 'wwwwww', 'create' => '123456' ]); } }
로그인 후 복사
실행 후 암호화는 NULL
数据完成:在数据字段insert,update,auto时进行处理 string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密NULL】 NULL【没有传值,$value=NULL】 string(32) "d41d8cd98f00b204e9800998ecf8427e"【加密$value,刚好等于NULL加密结果】
로그인 후 복사
나머지 $update 및 $insert는 $auto와 동일한 방식으로 사용됩니다. $auto에는 $update 및 $insert
Summary
수정자가 포함됩니다. 할당할 때 실행되고 데이터 완성은 할당할 때 한 번, 데이터를 쓸 때 한 번 실행됩니다. 모두가 함정을 피할 수 있습니다. 이해했다면 틀렸다면 정정해 주세요. 감사합니다