Zend RESTful身份验证

时间:2012-06-12 21:53:44

标签: php zend-framework authentication rest

我有一个网站(称之为siteA)我使用了php和Zend,我正在尝试实现一个api来访问我网站(SiteA)的受限区域(称之为SiteB)。

我希望能够使用SiteB凭据对siteB上的用户进行身份验证,为siteA提供一个html iframe,其中用户已通过API进行了身份验证。

我是新人,并不知道我是否朝着正确的方向前进。

到目前为止,我一直在考虑使用restful api,并在框架之外验证用户,但在框架中用户不是。

建议和帮助? 我的代码如下:

----- SiteB user / index.php ----

<html>
<body>
<?php
  $postdata = http_build_query(
   array(            
    'userid' => 'someid',
    'key' => 'somekey',
    'public' => '1'
   )
  );

$opts = array('http' =>
  array(
    'method'  => 'POST',
    'header'  => 'Content-type: application/x-www-form-urlencoded',
    'content' => $postdata
   )
 );

$context = stream_context_create($opts);
file_get_contents('https://www.siteA.com/api', false, $context);
?>

<iframe src="https://www.siteA.com/" width="950" height="700"></iframe>
</body>
</html>

----- SiteA ---------

<?php

class ApiController extends Zend_Controller_Action
{

    public function init()
    {
        /* Initialize action controller here */
        $this->_helper->viewRenderer->setNoRender(true);
        $this->_helper->layout->disableLayout();
    }


    public function indexAction() {
        if($this->getRequest()->isPost()){        
            $data = $this->_request->getPost();
            $this->_authenticateApi($data);
        }
        else{
            //error
        }

}
 public function _authenticateApi($data){
    $db = Zend_Registry::get('db_local');

    $authAdapter = new Zend_Auth_Adapter_DbTable($db);

    $authAdapter->setTableName('sometable');
    $authAdapter->setIdentityColumn('id');
    $authAdapter->setCredentialColumn('key');


    $authAdapter->setIdentity($data['id']);
    $authAdapter->setCredential($data['key']);

    $auth = Zend_Auth::getInstance();
    $result = $auth->authenticate($authAdapter);

    if($result->isValid()){
        if($data['public'] == "1"){
            Zend_Session::rememberMe(1209600);
        }else{
            Zend_Session::forgetMe();
        }
        return true;
    } else {
        return false;
    }
}

2 个答案:

答案 0 :(得分:2)

我最近遇到过这个问题。你必须使用iframe吗?对我来说这感觉很讨厌。

有很多方法可以做到这一点,但在我看来,似乎最佳做法是让API要求客户端使用HTTP Auth Basic进行身份验证,并使用HTTPS(SSL证书)来加密连接。在这种情况下,API不管理会话!每个请求都包含Auth Basic标头,就像您直接浏览API时常规Web浏览器一样。

然后,使用您的SiteB,当用户登录时,您将其凭据存储在$_SESSION或类似的地方,并在每次发出API请求时使用它们。

Subbu Allamaraju的

RESTful Web Services Cookbook是我最近阅读的一本很好的书,讨论了这个以及其他重要的RESTful API细节。

顺便说一句,它并不是真正的REST,除非您的客户端能够仅通过给定条目URL以及API所具有的媒体类型的知识来自行确定URL。搜索HATEOAS以获取更多信息。

此外,如果您尝试在JavaScript中执行所有这些操作并且SiteA和SiteB不共享同一个域,则可能会被迫使用JsonP来处理您的API请求。虽然可以做到,恕我直言,这是不可取的。在SiteB的PHP代码中使用Zend_Http_Client进行所有API通信。这样你就可以解决域名问题。这也可以防止您的API被窥探(右键单击,查看源代码!)并最大限度地减少任何跨浏览器兼容性问题的可能性,从而干扰您网站的核心功能。

答案 1 :(得分:0)

您可以尝试使用令牌,使用JS执行auth获取存储在Javascript变量中的令牌,并使用该令牌执行到站点A或站点B的“新”连接。

另请阅读OAuth以了解安全问题。不确定你的最终目标是什么......这是我的2美分。

致以最诚挚的问候,