如何在cakephp3中请求使用电子邮件和纯文本密码登录

时间:2018-05-18 07:35:25

标签: php rest cakephp android-webservice php-password-hash

我是 php 的新手,在我的Android应用程序中使用cakephp3 中的 REST API。

设置 php 作曲家和路由后,我创建了登录功能 ..

public function login() {
    $this->request->allowMethod('post');
    $this->loadModel('Users');
    $entity = $this->Users->newEntity($this->request->data, ['validate' => 'LoginApi']);
    if ($entity->errors()) {
        $this->httpStatusCode = 400;
        $this->apiResponse['message'] = 'Validation failed.';
        foreach ($entity->errors() as $field => $validationMessage) {
            $this->apiResponse['error'][$field] = $validationMessage[key($validationMessage)];
        }
    } else {
        $hasher = new DefaultPasswordHasher();
        $password = $hasher->hash($entity->password);

        $user = $this->Users->find()
            ->where([
                'email' => $entity->email,
                'password' => $password
            ])
            ->first();
        if (empty($user)) {
            $this->httpStatusCode = 403;
            $this->apiResponse['error'] = 'Invalid email or password.';
            return;
        }
        $payload = ['email' => $user->email, 'name' => $user->name];
        $this->apiResponse['token'] = JwtToken::generateToken($payload);
        $this->apiResponse['message'] = 'Logged in successfully.';
        isset($user);
        isset($payload);
    }
 }

我使用 123456 作为密码,此 hasher 每次都会返回随机字符串,但是已经保存在数据库中的密码为 123456 $ 2y $ 10 $ f7K02jamD7ZeGHLcTkP6Weh6VsthMWHiwqHJmcqbsxuLCKGCQCGCu 这个。

这就是为什么它会在响应中提供无效密码。

我的问题是如何匹配完全相同的字符串或哈希请求。 提前谢谢。

3 个答案:

答案 0 :(得分:1)

参考此answer

使用此行

password_verify($entity->password, $user->password)

而不是

$hasher = new DefaultPasswordHasher();
$password = $hasher->hash($entity->password);

你可以尝试这个功能

public function login()
{
    $this->request->allowMethod('post');
    $this->loadModel('Users');
    $entity = $this->Users->newEntity($this->request->data, ['validate' => 'LoginApi']);
    if ($entity->errors()) {
        $this->httpStatusCode = 400;
        $this->apiResponse['message'] = 'Validation failed.';
        foreach ($entity->errors() as $field => $validationMessage) {
            $this->apiResponse['error'][$field] = $validationMessage[key($validationMessage)];
        }
    } else {
        $user = $this->Users->find()->where(['email' => $entity->email])->first();
        if (count($user)) {
            if (password_verify($entity->password, $user->password)) {
                $payload = ['email' => $user->email, 'password' => $user->password];
                $this->apiResponse['token'] = JwtToken::generateToken($payload);
                unset($user->password);
                $this->apiResponse['response'] = array($user);
                unset($user);
                unset($payload);
            } else {
                $this->httpStatusCode = 403;
                $this->apiResponse['error'] = 'Incorrect password';
                return;
            }
        } else {
            $this->httpStatusCode = 403;
            $this->apiResponse['error'] = 'Email not found';
            return;
        }
    }
}

答案 1 :(得分:0)

一般的想法是根据您指定的密钥进行哈希。

建议是定期更换密钥。然后,您需要使用旧密钥再次将保存转换为清除,然后重新使用新密码。

我不确定你是否可以使用这个选项,所以你可能想要一点点。

干杯

答案 2 :(得分:0)

首先,CakePHP提供开箱即用的身份验证功能,我强烈建议您使用它而不是运行自己的身份,因为它听起来好像您正在寻找确定性算法,这很容易适得其反。

如果您正在使用CakePHP 3.5+,请查看authentication middleware plugin(目前处于RC阶段),对于早期的CakePHP版本,请使用authentication component

为了完整起见,如果您要手动执行此操作,您首先要通过其唯一标识符(在您的情况下是电子邮件地址)查询用户,然后使用密码保险程序在PHP级别比较密码AbstractPasswordHasher::check()实施:

$user = $this->Users
    ->find()
    ->where([
        'email' => $this->request->data('email')
    ])
    ->first();

if (!$user ||
    $hasher->check($this->request->data('password'), $user->password) !== true
) {
    // authentication failed
} else {
    // authentication succeeded
}