我有一个网站(称之为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;
}
}
答案 0 :(得分:2)
我最近遇到过这个问题。你必须使用iframe吗?对我来说这感觉很讨厌。
有很多方法可以做到这一点,但在我看来,似乎最佳做法是让API要求客户端使用HTTP Auth Basic进行身份验证,并使用HTTPS(SSL证书)来加密连接。在这种情况下,API不管理会话!每个请求都包含Auth Basic标头,就像您直接浏览API时常规Web浏览器一样。
然后,使用您的SiteB,当用户登录时,您将其凭据存储在$_SESSION
或类似的地方,并在每次发出API请求时使用它们。
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美分。
致以最诚挚的问候,