2014-03-02 74 views
3

我正在使用CakePHP構建一個Web應用程序。 我想使用bcrypt/Blowfish進行密碼加密。 用戶註冊工作正常,包括使用bcrypt散列密碼。 但不知何故,我不能登錄後 - 該應用程序說,用戶名/密碼錯誤,但輸入是正確的。CakePHP - 無法登錄用戶使用Blowfish Auth

這裏是我的關於授權代碼:

驗證的組件設定在AppController中:

public $components = array(
    'Session', 
    'Auth' => array(
     'loginAction' => array(
      'controller' => 'users', 
      'action' => 'login' 
     ), 
     'authenticate' => array(
      'Form' => array(
       'userModel' => 'User', 
       'passwordHasher' => 'Blowfish' 
      ) 
     ) 
    ) 
); 

型號代碼:

public $validate = array(
    'username' => array(
     'alphaNumeric' => array(
      'rule'  => 'alphaNumeric', 
      'required' => true, 
      'message' => 'Alphanumeric characters only' 
     ) 
    ), 
    'email'=> 'email', 
    'password' => array(
     'lengthrule' => array(
      'rule'  => array('minLength', '8'), 
      'message' => 'Minimum 8 characters' 
     ) 
    ) 
); 

public function beforeSave($options = array()) { 
    parent::beforeSave(); 
    $passwordHasher = new BlowfishPasswordHasher(); 
    $this->data['User']['password'] = $passwordHasher->hash(
     $this->data['User']['password'] 
    ); 
    if(empty($this->data[$this->alias]['token'])) { 
     $this->data[$this->alias]['token'] = md5(
      $this->data[$this->alias]['username'] . 
      $this->data[$this->alias]['email'] . 
      $this->data[$this->alias]['created'] 
     ); 
    } 

    return $this->data; 
} 

在我的控制器的登錄操作:

public function login() { 
    if ($this->request->is('post')) { 

     if ($this->Auth->login()) { 
      return $this->redirect(array('controller' => 'users', 'action' => 'edit')); 
     } 
     $this->Session->setFlash(__('Invalid username or password, try again')); 
    } 
} 

最後的元素,我試圖從登錄:

<div class="users form"> 
<?php echo $this->Session->flash('auth'); ?> 
<?php echo $this->Form->create('User', array('url' => '/users/login')); ?> 
    <fieldset> 
     <legend> 
      <?php echo __('Login :)'); ?> 
     </legend> 
     <?php echo $this->Form->input('username'); 
     echo $this->Form->input('password'); 
    ?> 
    </fieldset> 
<?php echo $this->Form->end(__('Login')); ?> 
<small>no account yet?</small><br /> 
<?php echo $this->Html->link(__('Register'), '/users/register'); ?> 
</div> 

更新

我發現散列串每次登錄嘗試改變 - 這可怎麼解決呢?鹽可能是隨機的嗎?不幸的是我沒有找到的文檔

相關UPDATE2

關於this post什麼,變更哈希可能是在這種情況下是正確的。 但我想,CakePHP在嘗試登錄時使用正確的鹽本身,對吧?

UPDATE3

隨着編輯BlowfishPasswordHasher類,如下所示:

public function check($password, $hashedPassword) { 
    var_dump(Security::hash($password, 'blowfish', $hashedPassword)); 
    return $hashedPassword === Security::hash($password, 'blowfish', $hashedPassword); 
} 

我現在確保奧赫componenent使用相同的散列爲每一個檢查。 但仍然 - 存儲在我的數據庫中的散列與散列器的檢查方法生成的散列不同。有任何想法嗎?

+0

您是否調試過「登錄」操作,對密碼值進行散列並比較生成的散列和存儲在數據庫中的散列? –

+0

哼 - 使用$ passwordHasher = new BlowfishPasswordHasher(); var $ dump($ passwordHasher-> hash($ this-> data ['User'] ['password']));在我的登錄行爲中,哈希值實際上是不同的。任何想法爲什麼這可能發生? – Revoluzifer

+0

更新我的問題 - 似乎相當複雜 – Revoluzifer

回答

2

我發現我的錯誤。

除了我的用戶註冊,我實施了電子郵件驗證。 驗證時,用戶記錄正在被修改,並且對User-> save()的相應調用導致密碼在beforeSave()中再次被散列。

因此,對我來說有效的是使用我的beforeSave()代碼,但只有密碼字段再次散列時,如果令牌字段爲空,在我的情況下,只能在註冊時發生,而不是驗證時或驗證後。

2

嘗試使用自定義的哈希算法,使用php-methods使用blowfish哈希密碼。請參閱有關的新方法的PHP文件在這裏:

1.Hash密碼上beforeSave()在你的模型:

public function beforeSave() 
{ 
    $this->data['User']['password'] = password_hash(
     $this->data['User']['password'], 
     PASSWORD_BCRYPT 
    ); 

    return true; 
} 

2.Define定製散列器中您的AppController的組件Auth

public $components = array(
    'Session', 
    'Auth' => array(
     'loginAction' => array(
      'controller' => 'users', 
      'action' => 'login' 
     ), 
     'authenticate' => array(
      'Form' => array(
       'userModel' => 'User', 
       'passwordHasher' => 'Custom' 
      ) 
     ) 
    ) 
); 

3。在app/Controller/Component/Auth/CustomPasswordHasher.php創建自定義哈希:

App::uses('AbstractPasswordHasher', 'Controller/Component/Auth'); 
class CustomPasswordHasher extends AbstractPasswordHasher 
{ 
    public function hash($password) 
    { 
     return $password; 
    } 

    public function check($password, $hashedPassword) 
    { 
     return password_verify($password, $hashedPassword); 
    } 
} 

那就是所有。適用於我。

+0

感謝您的答案 - 將嘗試儘快:) – Revoluzifer

+0

再次感謝,基本上你的代碼工作很好,但我的問題是別的。 (如果對愚蠢感興趣,請參閱我的最新答案;)) – Revoluzifer