2012-07-25 115 views
0

我正在爲登錄用戶構建一個表單來更改他們的帳戶設置(電子郵件和密碼)。要做到這一點,他們需要能夠確認他們當前的密碼。這就是我如何建立我的形式settings.ctp更改帳戶設置時檢查用戶當前的密碼

<div id="content-complex-image"> 
    <div id="sidebar"> 
     <ul> 
      <li><a href="/account/images">Your images</a></li> 
      <li><a href="/account/settings">Account settings</a></li> 
     </ul> 
    </div> 
    <div id="content-inner"> 
     <p>Modify your account settings</p> 
     <?php echo $this->Session->flash(); ?> 
     <?php 
      echo $this->Form->create('User'); 
      echo $this->Form->input('currentPassword', array('type' => 'password')); 
      echo $this->Form->input('username', array('disabled' => 'disabled', 'value' => $username)); 
      echo $this->Form->input('email'); 
      echo $this->Form->input('password', array('type' => 'password')); 
      echo $this->Form->end('Update'); 
     ?> 
    </div> 
    <div class="clear"></div> 
</div> 

,這是我的控制器操作:

public function settings() { 
    $this->set('title_for_layout', 'Account Settings'); 

    $this->User->id = $this->Auth->user('id'); 
    if ($this->request->is('post')) { 
     if($this->Auth->user('password') == $this->request->data['User']['currentPassword']) { 
      if ($this->User->save($this->request->data)) { 
       $this->Session->setFlash('Your details have been saved'); 
       $this->redirect(array('action' => 'settings')); 
      } else { 
       $this->Session->setFlash('Your details could not be updated. Try again.'); 
      } 
     } else { 
      $this->Session->setFlash('Invalid password. Try again.'); 
     }    
    } 
} 

然而,if()密碼檢查結果始終爲假,總是顯示「無效密碼「消息。我猜測我沒有正確地檢查密碼,但我不知道這樣做的正確方法。

此外,我不希望用戶能夠更改他們的用戶名。我知道我已將表單字段設置爲禁用,但如果用戶向我的設置操作發送了發佈請求,他們可以更改其用戶名。如何阻止用戶名更新爲$this->User->save()

編輯:看起來像兩個問題,其中一個,我沒有在比較和兩個之前哈希密碼,$this->Auth->user('password')實際上是NULL。這引發了另一個問題,我如何從數據庫中獲取用戶哈希密碼以便比較它?

+2

密碼是否使用明文存儲在數據庫中?如果沒有,那會導致您的驗證檢查失敗。 – nick 2012-07-25 22:17:40

+0

它使用Cake的默認哈希算法,我相信它是sha1? – 2012-07-25 22:25:12

+0

您還需要對'currentPassword'進行散列,以便它匹配任何'Auth :: user('password')' – Ross 2012-07-25 22:25:59

回答

0

如果密碼未作爲明文存儲在您的數據庫中,那麼由於您未對從表單傳遞的數據進行編碼/加密,所以密碼檢查將失敗。一個簡單的方法來檢查(只是一個測試機請)將與

$this->Session->setFlash('The password should be ' . $this->Auth->user('password') . 'but it is actually ' . $this->request->data['User']['currentPassword']); 

或類似的東西來取代$this->Session->setFlash('Invalid password. Try again.');

希望它可以幫助

編輯:

如果密碼是使用SHA1存儲,您可以檢查它像這樣

if($this->Auth->user('password') == sha1($this->request->data['User']['currentPassword'])) 
{ 
    //code for successful password here 
} 
+0

這樣做後,我得到這個:'密碼應該是,但它實際上是密碼'。在'$ this-> Auth-> user('password')上執行'var_dump'後,我看到它是NULL。看起來Cake不會將用戶密碼存儲在Auth組件中,就像存儲用戶名和用戶標識一樣。 :( – 2012-07-25 22:33:15

+1

您可能想驗證用戶是否基於其他內容,如會話ID?Auth組件可能在Session對象中,這對於惡意用戶來說太容易劫持了。 – nick 2012-07-25 22:36:31

+0

我應該補充說明我沒有之前使用過Cake,只是普通的PHP。 – nick 2012-07-25 22:37:23

0

你是正確的關於驗證組件不持密碼在它的數據。試試這個代碼:

public function settings() { 
    $this->set('title_for_layout', 'Account Settings'); 

    if ($this->request->is('post')) { 
     $user = $this->User->findById($this->Auth->user('id')); 
     if($user['User']['password'] == AuthComponent::password($this->request->data['User']['currentPassword'])) { 
      if ($this->User->save($this->request->data)) { 
       $this->Session->setFlash('Your details have been saved'); 
       $this->redirect(array('action' => 'settings')); 
      } else { 
       $this->Session->setFlash('Your details could not be updated. Try again.'); 
      } 
     } else { 
      $this->Session->setFlash('Invalid password. Try again.'); 
     }    
    } 
} 

而我的建議,阻止他們改變他們的用戶名是隻是放棄這個輸入?你可以簡單地回顯他們的用戶名,而不是有一個禁用的輸入框。

+0

謝謝,作品。我可以禁用輸入,但由於Cake處理用戶保存的方式,用戶仍然可以通過用'username'參數向該頁面發送POST請求來更改他們的用戶名。我選擇使用'unset()'來確保即使'username'字段被髮送,它也會被丟棄。 – 2012-07-25 23:24:34

+1

我沒有考慮save()函數如何處理保存,unset()正是你在這種情況下應該使用的。另外,如果你想優化查詢,你可以使用包含來確保它只返回你需要的數據。 – 2012-07-25 23:26:40