在CakePHP 2.0中,每个请求都可以进行无状态HTTP基本/摘要身份验证


Is per-request, stateless HTTP Basic/Digest authentication possible in CakePHP 2.0?

手册不清楚如何实现这一点(它假设你已经知道自己在做什么,在某些情况下感觉像是事后才想到的),我一直在努力弄清楚这一点。

问题:通过HTTP验证头对所有API请求进行身份验证

就我所能测试的而言,我可以在CakePHP中使用基本身份验证和基于普通表单的登录,但只有首先点击我在身份验证组件中定义的login操作。当我直接访问该网站时,这很好,并且按预期工作(除了Digest,它似乎完全被窃听了)。不过,通过cURL,我没有运气,除非我已经登录。

显然,对于API来说,这远不是理想的。我不想在做我想做的事情之前向/login发布请求,我也不能指望用户手动登录,这样Cake就有一个cookie可以读取。它需要是无国籍的。

任何提供身份验证凭据的尝试以及我(通过cURL)发出的每个请求都将被忽略,返回403错误。CCD_ 3方法或任何CCD_。

我需要做些什么才能让Cake表现得像一个真正的API,并允许我在每次请求的基础上进行庄严授权?我是否必须推出自己的解决方案?

我有一个集中式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;
}