如何在cakephp3中请求使用电子邮件和纯文本密码登录
How to request for login with email and plain text password in cakephp3
我是 php 的新手,正在 cakephp3[=31= 中从事 REST API ] 我的 android 申请。
设置 php 和 composer 和路由后,我创建了 登录函数 ..
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 returns 随机字符串每次,但是已经保存在数据库中的 123456 的密码是
$2y$10$f7K02jamD7ZeGHLcTkP6Weh6VsthMWHiwqHJmcqbsxuLCKGCQCGCu 这个。
这就是它给出无效密码作为响应的原因。
我的问题是如何为请求匹配完全相同的字符串或散列。
提前致谢。
一般的想法是根据您指定的密钥进行散列。
一个建议是定期更改密钥。然后,您将需要使用旧密钥再次将您的保存解密为明文,然后在新密钥上重新哈希。
我不确定您是否可以使用该选项,因此您可能希望对它持保留态度。
干杯
首先,CakePHP 附带了开箱即用的身份验证功能,我强烈建议您使用它而不是 运行 自己的,因为它听起来就好像您正在寻找确定性算法一样,这很容易适得其反。
如果您使用的是 CakePHP 3.5+,请查看 authentication middleware plugin (currently in RC phase), for earlier CakePHP versions, use the 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
}
参考这篇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;
}
}
}
我是 php 的新手,正在 cakephp3[=31= 中从事 REST API ] 我的 android 申请。
设置 php 和 composer 和路由后,我创建了 登录函数 ..
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 returns 随机字符串每次,但是已经保存在数据库中的 123456 的密码是 $2y$10$f7K02jamD7ZeGHLcTkP6Weh6VsthMWHiwqHJmcqbsxuLCKGCQCGCu 这个。
这就是它给出无效密码作为响应的原因。
我的问题是如何为请求匹配完全相同的字符串或散列。 提前致谢。
一般的想法是根据您指定的密钥进行散列。
一个建议是定期更改密钥。然后,您将需要使用旧密钥再次将您的保存解密为明文,然后在新密钥上重新哈希。
我不确定您是否可以使用该选项,因此您可能希望对它持保留态度。
干杯
首先,CakePHP 附带了开箱即用的身份验证功能,我强烈建议您使用它而不是 运行 自己的,因为它听起来就好像您正在寻找确定性算法一样,这很容易适得其反。
如果您使用的是 CakePHP 3.5+,请查看 authentication middleware plugin (currently in RC phase), for earlier CakePHP versions, use the 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
}
参考这篇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;
}
}
}