2

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

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

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

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

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

----- SiteB 用户/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>

----- 站点A ---------

<?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;
    }
}
4

2 回答 2

2

我最近遇到了这个问题。您是否有理由必须使用 iframe?这对我来说有点骇人听闻。

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

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

Subbu Allamaraju 的RESTful Web Services Cookbook是我最近读到的一本很棒的书,它讨论了这个和其他重要的 RESTful API 细节。

顺便说一句,它并不是真正的 RESTful,除非您的客户端能够仅通过输入 URL 和 API 功能的媒体类型知识自行找出所有 URL。搜索 HATEOAS 了解更多信息。

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

于 2012-06-12T22:30:41.837 回答
0

您可以尝试使用令牌,使用 JS 进行身份验证获取存储在 Javascript 变量中的令牌,然后使用该令牌与站点 A 或站点 B 进行“新”连接。

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

此致,

于 2012-06-12T22:30:32.553 回答