CodeIgniter REST API Library Ajax PUT throwing 403

2019-02-09 14:52发布

问题:

I got the rest of the library working fully, just trying to generate api keys and its throwing a 403 forbidden when executed via ajax.

({"status":false,"error":"Invalid API Key."})

I traced it to _remap function under REST_Controller.. almost as if im calling the url incorrectly?

workflow: user visits site1.com -> registers for account -> generates api key for their domain -> key recorded in db -> key displayed

The following form would be on site1.com after they register for an account they would click "generate key".

ajax call:

/**
 * 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]);
            };
        }
    });
 });

REST-SERVER on GitHub: https://github.com/philsturgeon/codeigniter-restserver

look specifically at key.php under application/controllers/api/key.php

Snippet of the key.php file that should relate to this process:

/**
 * 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
    }
}

Response/Request Headers

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:

i ended up finding out the 403 forbidden was because i was not providing an api key to generate keys..

Kind of abiguous as Phil's documentation doesn't state that an existing api key is required before you can generate keys..

I simply created a bogus key in the table in the db and referenced that when calling /key/index?X-API-KEY=boguskey



回答2:

I have solved the problem of generating the api key. I'm using Phil Sturgeon's REST API server. Call the key controller using ajax call as such :

$("#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]);
            };
        }
    });
 });

Inside key controller: Search for function _generate_key() and check for $this->load->helper('security');. the security helper must be loaded for working of do_hash otherwise you will get 500 internal server error.

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
    }
}

Also, you may call http://sitename.com/api/keyindex?X-API-KEY=your_key_here in your browser's address bar by making a small change in your key controller you can replace the function name index_put with index_get.

Thanks



回答3:

If you are calling this from a different domain, you may be running into some XSS issues. You might have to run it from your own server and call the function from it's own domain or possibly use the JSONP capability.

UPDATE: Are you able to see the transaction in Firebug using the NET Tab? Do you get JSON Back? Sometimes you have to add callback=? to the url request: http://dev.site1.com/api/key?callback=?

Update2: Are you able to bring the page up in the browser: (http://dev.mapitusa.com/api/key) If you get the same error, you should try giving 777 (full read/write) permissions to the site.



回答4:

This sounds like it might be a browser issue. Maybe an incorrect implementation of PUT in the XMLHttpRequest stack.

I would try converting it quickly to POST just to see if it works. It might be better off leaving it as POST anyway just for compatibility purposes.