我是 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 这个。
这就是为什么它会在响应中提供无效密码。
我的问题是如何匹配完全相同的字符串或哈希请求。 提前谢谢。
答案 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
}