手册目前还不清楚如何实现这一点(它假设你已经知道你正在做什么,在某些情况下感觉就像是事后的想法),而且我一直在试图弄清楚我的头脑它出来了。
就我能够测试而言,我可以在CakePHP中使用Basic auth和普通的基于表单的登录,但是首先点击我定义的login
操作 在Auth组件中。当我直接访问该站点时,这很好,并按预期工作(Digest除外,它似乎完全错误)。但是,通过cURL,除非我已经登录,否则我没有运气。
显然,对于API来说,这远非理想。在做我想做的事情之前,我不想向/login
发布请求,我不能指望用户手动登录,因此Cake有一个cookie可供阅读。它需要是无国籍的。
任何尝试提供身份验证凭据以及我发出的每个请求(通过cURL)都会被忽略,我收到403错误。 <{1}}方法或任何login
类都没有被触及。
我需要做些什么才能使Cake的行为像实际的API一样,并允许我在每个请求的基础上进行无状态授权?我是否必须推出自己的解决方案?
答案 0 :(得分:4)
我有一个集中式API,允许通过HTTP摘要进行用户身份验证,并要求用户登录许多与用户相关的功能。 CakePHP强制登录的方式是检查操作是否需要登录,重定向到您的登录操作(默认为/ users / login),然后您可以重定向回来。
我通过执行以下操作创建了我的API:
//Config/routes.php
///////////////////////////
/**
* Users Controller routes for REST API
*/
Router::mapResources('users');
/**
* Parses extensions for data serialization
*/
Router::parseExtensions();
//Controller/UserController.php
////////////////////////////////
<?php
App::uses('DigestAuthenticate', 'Controller/Component/Auth/');
class UsersController extends AppController {
var $name = 'Users';
//Login callback
function login() {
//dont render for login, just a call back for auth
$this->autoRender = false;
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
}
}
//GET /users.[xml|json]
//this is the basic call that tests user authentication
//basically a login then echo
function index() {
if ($this->Auth->login()) {
$user = $this->Auth->user();
$this->User->id = $user['id'];
$this->User->saveField('last_login', date('Y-m-d H:i:s'));
$this->set('response', array(
'response' => array(
'code' => 'users_auth_success',
'message' => 'User has passed authentication',
'data' => $user
)
));
//will serialize to xml or json based on extension
$this->set('_serialize', 'response');
}
}
}
?>
然后,您可以在以下内容中使用此API:
$c = curl_init($uri . '.' . $this->_format);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_USERPWD, $login['user'] . ':' . $login['pass']);
curl_setopt($c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($c);
$info = curl_getinfo($c);
curl_close($c);
if($info['http_code'] == $this->_http_codes['OK']) {
//success
if($this->_format == 'xml')
$response = Xml::toArray(Xml::build($response));
else//JSON
$response = json_decode($response);
return $response['response']['data'];
} else if($info['http_code'] == $this->_http_codes['Unauthorized']) {
return false;
} else {
return null;
}