CodeIgniter REST API 库 Ajax PUT 抛出 403 Forbidden
Posted
技术标签:
【中文标题】CodeIgniter REST API 库 Ajax PUT 抛出 403 Forbidden【英文标题】:CodeIgniter REST API Library Ajax PUT throwing 403 Forbidden 【发布时间】:2012-02-26 08:13:33 【问题描述】:我让库的其余部分完全正常工作,只是尝试生成 api 密钥并在通过 ajax 执行时抛出 403 禁止。
("status":false,"error":"Invalid API Key.")
我追踪到 REST_Controller 下的 _remap 函数。几乎就像我错误地调用了 url?
工作流程: user visits site1.com -> registers for account -> generates api key for their domain -> key recorded in db -> key displayed
以下表格将在他们注册帐户后出现在 site1.com 上,他们将点击“生成密钥”。
ajax 调用:
/**
* Generate an API Key for Us to use
*/
$("#submitGetApiKey").click(function()
$.ajax(
url: "http://dev.site1.com/api/key",
crossDomain: true,
type: "PUT",
dataType: "jsonp",
error: function(XMLHttpRequest, textStatus, errorThrown)
alert(errorThrown);
,
success: function(data)
for (var i = keys.length - 1; i >= 0; i--)
console.log(keys[i]);
;
);
);
GitHub 上的 REST-SERVER:https://github.com/philsturgeon/codeigniter-restserver
具体看application/controllers/api/key.php
下的key.php
应该与此过程相关的 key.php 文件的片段:
/**
* Key Create
*
* Insert a key into the database.
*
* @access public
* @return void
*/
public function index_put()
// Build a new key
$key = self::_generate_key();
// If no key level provided, give them a rubbish one
$level = $this->put('level') ? $this->put('level') : 1;
$ignore_limits = $this->put('ignore_limits') ? $this->put('ignore_limits') : 1;
// Insert the new key
if (self::_insert_key($key, array('level' => $level, 'ignore_limits' => $ignore_limits)))
$this->response(array('status' => 1, 'key' => $key), 201); // 201 = Created
else
$this->response(array('status' => 0, 'error' => 'Could not save the key.'), 500); // 500 = Internal Server Error
响应/请求标头
Request URL:http://dev.mapitusa.com/api/key
Request Method:PUT
Status Code:403 Forbidden
Request Headersview source
Accept:application/json, text/javascript, */*; q=0.01
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3
Accept-Encoding:gzip,deflate,sdch
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:0
Cookie:ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22e165df34aa4fda5936e940658030f83d%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A118%3A%22Mozilla%2F5.0+%28Macintosh%3B+Intel+Mac+OS+X+10_7_3%29+AppleWebKit%2F535.19+%28Khtml%2C+like+Gecko%29+Chrome%2F18.0.1025.3+Safari%2F535.19%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1328291821%3B%7Dac0f163b112dbd3769e67f4bb7122db2
Host:dev.mapitusa.com
Origin:http://dev.mapitusa.com
Referer:http://dev.mapitusa.com/api_test.html
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.3 Safari/535.19
Response Headersview source
Cache-Control:max-age=0, public
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:69
Content-Type:application/json
Date:Fri, 03 Feb 2012 18:03:54 GMT
Expires:Fri, 03 Feb 2012 18:03:54 GMT
Keep-Alive:timeout=5, max=98
Server:Apache
Set-Cookie:ci_session=a%3A4%3A%7Bs%3A10%3A%22session_id%22%3Bs%3A32%3A%22f2f466f7b97b89f2a9b557d2d9a0dbcc%22%3Bs%3A10%3A%22ip_address%22%3Bs%3A9%3A%22127.0.0.1%22%3Bs%3A10%3A%22user_agent%22%3Bs%3A118%3A%22Mozilla%2F5.0+%28Macintosh%3B+Intel+Mac+OS+X+10_7_3%29+AppleWebKit%2F535.19+%28KHTML%2C+like+Gecko%29+Chrome%2F18.0.1025.3+Safari%2F535.19%22%3Bs%3A13%3A%22last_activity%22%3Bi%3A1328292234%3B%7D6821b96c7e58b55f1767eb265ffdb79e; expires=Fri, 03-Feb-2012 20:03:54 GMT; path=/
Status:403
Vary:Accept-Encoding,User-Agent
X-Powered-By:PHP/5.3.6
X-UA-Compatible:IE=Edge,chrome=1
【问题讨论】:
【参考方案1】:我最终发现 403 被禁止是因为我没有提供 api 密钥来生成密钥..
有点模棱两可,因为 Phil 的文档没有说明在生成密钥之前需要现有的 api 密钥..
我只是在 db 的表中创建了一个伪造的密钥,并在调用 /key/index?X-API-KEY=boguskey 时引用了它
【讨论】:
你可以只将一个塞入数据库,如果你不想使用,你不必明确地使用 api 生成控制器。事实上,您可以在应用程序中创建随机密钥,然后也可以将它们放入数据库中。它是通用的,你可以做你喜欢的;) 我有同样的问题,我生成一个密钥,因为你我的不工作,帮助我【参考方案2】:我已经解决了生成api密钥的问题。 我正在使用 Phil Sturgeon 的 REST API 服务器。 使用 ajax 调用这样的键控制器:
$("#submitGetApiKey").click(function()
$.ajax(
url: "http://sitename.com/api/key/index?X-API-KEY=your_key_here",
crossDomain: true, /* remove this if using the same domain*/
type: "PUT",
dataType: "jsonp",
error: function(XMLHttpRequest, textStatus, errorThrown)
alert(errorThrown);
,
success: function(data)
for (var i = keys.length - 1; i >= 0; i--)
console.log(keys[i]);
;
);
);
内部按键控制器: 搜索函数 _generate_key() 并检查 $this->load->helper('security');。必须加载安全助手才能运行 do_hash 否则您将收到 500 内部服务器错误。
public function index_put()
// Build a new key
$key = self::_generate_key();
// If no key level provided, give them a rubbish one
$level = $this->put('level') ? $this->put('level') : 1;
$ignore_limits = $this->put('ignore_limits') ? $this->put('ignore_limits') : 1;
// Insert the new key
if (self::_insert_key($key, array('level' => $level, 'ignore_limits' => $ignore_limits)))
$this->response(array('status' => 1, 'key' => $key), 201); // 201 = Created
else
$this->response(array('status' => 0, 'error' => 'Could not save the key.'), 500); // 500 = Internal Server Error
此外,您可以在浏览器的地址栏中调用http://sitename.com/api/keyindex?X-API-KEY=your_key_here,只需对您的密钥控制器进行一些小改动 您可以将函数名 index_put 替换为 index_get。
谢谢
【讨论】:
【参考方案3】:如果您从不同的域调用它,您可能会遇到一些 XSS 问题。您可能必须从自己的服务器运行它并从它自己的域调用该函数,或者可能使用 JSONP 功能。
更新:您是否能够使用 NET 选项卡在 Firebug 中查看事务? 你得到 JSON 回来了吗? 有时您必须添加回调=?到 url 请求: http://dev.site1.com/api/key?callback=?
Update2:你能在浏览器中打开页面吗:(http://dev.mapitusa.com/api/key) 如果您遇到同样的错误,您应该尝试为该站点授予 777(完全读/写)权限。
【讨论】:
更新了问题,对工作流程/场景进行了更多解释 当我拉起 api/key 时,它会触发 index_get 而不是 index_put,这样就不可能了...... 页面无法通过直接调用 API URL 来查找 PUT 标头而不是 GET。我需要模仿 PUT 才能挑出 ajax。这些文件确实有 777 chmod【参考方案4】:这听起来可能是浏览器问题。可能是 XMLHttpRequest 堆栈中的 PUT 实现不正确。
我会尝试快速将其转换为 POST 以查看它是否有效。出于兼容性目的,将其保留为 POST 可能会更好。
【讨论】:
以上是关于CodeIgniter REST API 库 Ajax PUT 抛出 403 Forbidden的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有数据的http标头发送到rest Api codeigniter?
是否有一个带有/ORM(Laravel、Cake、Codeigniter)的 PHP 框架,我们可以在其中覆盖数据交互以从 rest api 中获取数据?
Phonegap错误:401未经授权 - 在Phonegap中使用基本身份验证的Rest API