在开始之前,完全免责声明,我刚开始使用CakePHP,摘要式身份验证,主要参考Cookbook和StackOverflow作为指导。
对于手头的问题,我正在尝试构建一个相当简单的rest api(使用this作为起点,this作为路由)。没有身份验证,我已经能够使路由工作,并且终点(例如/api/v1/notices.json
)正如预期的那样返回json响应。一切都很好,直到这一点。下一步是在混合中添加摘要式身份验证。
这是事情向南的地方。在Cookbook的Authentication部分之后,我确实放置了所需的代码。
这是UsersController.php初始化方法,
public function initialize()
{
$this->loadComponent('Auth', [
'authenticate' => [
'Digest' => [
'fields' => ['username' => 'username', 'password' => 'digest_hash'],
'userModel' => 'Users'
],
],
'storage' => 'Memory',
'unauthorizedRedirect' => false
]);
}
这是NoticesController.php初始化方法,
public function initialize()
{
parent::initialize();
$this->loadComponent('Auth', [
'authenticate' => [
'Digest' => [
'fields' => ['username' => 'username', 'password' => 'digest_hash'],
'userModel' => 'Users'
],
],
'storage' => 'Memory',
'unauthorizedRedirect' => false
]);
}
这是UsersTable.php beforeSave方法,
public function beforeSave(Event $event)
{
$entity = $event->getData('entity');
// Make a password for digest auth.
$entity->digest_hash = DigestAuthenticate::password(
$entity->username,
$entity->password,
env('SERVER_NAME')
);
return true;
}
每当我尝试访问/api/v1/notices.json
在用户名字段中提供my_username并在密码字段中提供用户的digest_hash值时,使用Postman。这样做我得到了未经授权的消息作为json响应的一部分。以下是Postman发送的数据,
GET /api/v1/notices.json HTTP/1.1
Host: localhost:8765
Authorization: Digest username="my_username", realm="", nonce="",
uri="/api/v1/notices.json",
response="ab5a2441f5396e223efd48a0a0c205b9", opaque=""
Cache-Control: no-cache
Postman-Token: 715dbb84-ab72-8b68-bf77-5eee01b9cc2c
尝试从谷歌浏览器访问同一个端点导致一个接一个的登录弹出窗口,并且根本没有完成。
任何帮助将不胜感激!
更新:以下是表用户的数据库方案,
我正在以纯文本和digest_hash存储(暂时)密码,以及存储散列值。
更新2:我相信,响应哈希是由Postman生成的。虽然我没有专门定义领域,qop,nonce等的值,但它们是作为标题的一部分发送的(参见下图),
我有责任将digest_hash和密码存储为二进制(64)。应该使用blob(或varchar)。
答案 0 :(得分:0)
这很可能是因为您在邮递员请求中提供空字符串作为领域。
DigestAuthenticate :: password()的第三个参数必须与在AuthComponent :: $ authenticate中配置DigestAuthentication时定义的'realm'配置值匹配。这默认为env(' SCRIPT_NAME')。如果要在多个环境中保持一致的哈希值,可能希望使用静态字符串。
定义摘要密码时,您提供env('SERVER_NAME')
作为领域。这意味着您必须用静态字符串替换它或更改请求以便提供正确的域。
示例强>
$entity->digest_hash = DigestAuthenticate::password(
$entity->username,
$entity->password,
'My Realm'
);