旧版密码哈希不工作将CodeIgniter2迁移到Cake 3

时间:2016-10-13 16:38:59

标签: cakephp cakephp-3.0

我有一个旧的CRM应用程序,我正在从Code Igniter 2.x迁移到Cake 3.我正在尝试实现Legacy Password Hasher,然后将所有内容移动到Cake 3密码hasher。

我无法让身份验证工作。正如您将看到我不得不偏离各种蛋糕默认值,特别是所有表都是以单数名称创建的。不确定是否会导致任何问题。这是一场考验。如果重要,Admin就作为插件存在。

AppController的

namespace Admin\Controller;

use App\Controller\AppController as BaseController;

class AppController extends BaseController
{
    public function initialize() {
        parent::initialize();
        $this->loadComponent('Auth', [
            'loginAction' => '/admin/login', // routes to /admin/user/login
            'authenticate' => [
                'Form' => [
                    'passwordHasher' => [
                        'className' => 'Legacy',
                    ],
                    'fields' => [
                        'username' => ['email_address','handle'], 
                        'password' => 'password',
                    ],
                    'userModel' => 'User',
                ],
            ],
            'storage' => 'Session'
        ]);
    }
}

UserController中

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

    $this->loadModel('User');
    $me = $this->User->find()->where([
                'type IN ' => ['superuser','administrator','user','publisher'],
                'status IN ' => ['active','suspended'],
                'OR' => [
                    'email_address' => $this->request->data('username'), 'handle' => $this->request->data('username')
                ]
            ])->first();

    if( $me->status == 'active' ){

        $user = $this->Auth->identify();
        if( $user ){
            $this->Auth->setUser($user);
            if( $this->Auth->authenticationProvider()->needsPasswordRehash() ){
                $user = $this->User->get($this->Auth->user('id'));
                $user->password = $this->request->data('password');
                $this->User->save($user);
            }
            switch($user->type){
                case 'superuser':
                    $url = '/admin/dashboard/super';
                    break;
                case 'admin':
                    $url = '/admin/dashboard/';
                    break;
                case 'publisher':
                    $url = '/admin/dashboard/publisher';
                    break;
                case 'property':
                    $url = '/admin/dashboard/property';
                    break;
            }

            return $this->redirect($url);
        }
    }
    $this->Flash->error(__('Username or password is incorrect'), [
        'key' => 'auth'
    ]);
}

LegacyPasswordHasher

namespace App\Auth;

use Cake\Auth\AbstractPasswordHasher;

class LegacyPasswordHasher extends AbstractPasswordHasher
{

    public function hash($password){
        $salt_length = 16;
        $salt = substr($password, 0, $salt_length);

        return $salt . sha1($salt . $password);
    }

    public function check($password, $hashedPassword){
        return $this->hash($password) === $hashedPassword;
    }
}

传统密码hasher似乎甚至没有被调用。我通过自己的检查然后设置auth用户数据来强制执行身份验证。在此之后,当使用Cakes DefaultPasswordHasher身份验证重新密码时失败。

1 个答案:

答案 0 :(得分:0)

我想出来了。这里有一些问题。一,我需要将配置更改为:

    $this->loadComponent('Auth', [
        'loginAction' => '/admin/login',
        'authenticate' => [
            'Form' => [
                'finder' => 'auth',
                'passwordHasher' => [
                    'className' => 'Legacy',
                ],
                'fields' => [
                    'username' => 'email_address', 
                    'password' => 'password',
                ],
                'userModel' => 'User',
            ],
        ],
        'storage' => 'Session'
    ]);

接下来,我发布的字段需要是email_address而不是用户名。最后,我的Code Igniters密码hasher实现中存在一个错误。它最终需要看起来像这样:

public function hash($password){
    $salt_length = 16;
    $salt = substr($this->salt, 0, $salt_length);

    return $salt . sha1($salt . $password);
}

public function check($password, $hashedPassword){
    $this->salt = $hashedPassword;
    return $this->hash($password) === $hashedPassword;
}

我还需要添加到UserTable的自定义查找器查询:

public function findAuth(\Cake\ORM\Query $query, array $options)
{
    $query
        ->select(['id', 'email_address','handle','password'])
        ->where(['User.status' => 'active']);

    return $query;
}

要处理能够使用用户名或email_address登录的用户,如果不是电子邮件地址,我将覆盖已发布的值,方法是在auth执行此操作之前通过句柄查找用户。

我希望这有助于某人。