REST用户注册和通过Api密钥登录

时间:2016-10-30 11:30:51

标签: codeigniter rest codeigniter-3 codeigniter-restserver

我不是codeignitor的新手,但我仍然没有使用他们称为“API密钥”身份验证的功能。

我想做什么?

  • my_users表中注册用户,并且apikey作为列,应在用户注册时存储并生成唯一的API。
  • 登录用户,用户提供用户名,密码并在收到正确信息的情况下获得响应,并在apikey表中分别显示my_users
  • 登录后,我想将apikey用于所有其他用户相关的呼叫,例如bookATask,标题为X-API-KEY,这将允许我控制客户端的用户会话并保护登录和签名系统。< / LI>

设置问题:

  • 每当我发出请求传递X-API-KEY时,我都会被问到这是错误的,因为在register_post控制器中可能有User调用注册用户且Api密钥无法传递在标题中,除非它是在这种方法中生成的吗?
  • 我刚收到状态:FALSE和错误:Invalid Api key每次拨打电话。

我在做什么?

(仅更改了代码)

应用/配置/ rest.php

defined('BASEPATH') OR exit('No direct script access allowed');
$config['force_https'] = FALSE;
$config['rest_default_format'] = 'json';
$config['rest_supported_formats'] = [
    'json',
    'array',
    'csv',
    'html',
    'jsonp',
    'php',
    'serialized',
    'xml',
];
$config['rest_status_field_name'] = 'status';
$config['rest_message_field_name'] = 'error';
$config['enable_emulate_request'] = TRUE;
$config['rest_realm'] = 'REST API';
$config['rest_auth'] = 'basic';
$config['auth_source'] = '';
$config['allow_auth_and_keys'] = TRUE;
$config['auth_library_class'] = '';
$config['auth_library_function'] = '';
$config['auth_override_class_method_http']['user']['register']['post'] = 'none';
$config['auth_override_class_method_http']['user']['login']['post'] = 'none';
$config['rest_valid_logins'] = ['user1' => '12345'];
$config['rest_ip_whitelist_enabled'] = FALSE;
$config['rest_ip_whitelist'] = '';
$config['rest_ip_blacklist_enabled'] = FALSE;
$config['rest_ip_blacklist'] = '';
$config['rest_database_group'] = 'default';
$config['rest_keys_table'] = 'my_users';
$config['rest_enable_keys'] = TRUE;
$config['rest_key_column'] = 'apikey';
$config['rest_limits_method'] = 'ROUTED_URL';
$config['rest_key_length'] = 40;
$config['rest_key_name'] = 'X-API-KEY';
$config['rest_enable_logging'] = TRUE;
$config['rest_logs_table'] = 'app_logs';
$config['rest_enable_access'] = FALSE;
$config['rest_access_table'] = 'access';
$config['rest_logs_json_params'] = FALSE;
$config['rest_enable_limits'] = TRUE;
$config['rest_limits_table'] = 'app_limits';
$config['rest_ignore_http_accept'] = FALSE;
$config['rest_ajax_only'] = FALSE;
$config['rest_language'] = 'english';
$config['check_cors'] = FALSE;
$config['allowed_cors_headers'] = [
  'Origin',
  'X-Requested-With',
  'Content-Type',
  'Accept',
  'Access-Control-Request-Method'
];
$config['allowed_cors_methods'] = [
  'GET',
  'POST',
  'OPTIONS',
  'PUT',
  'PATCH',
  'DELETE'
];
$config['allow_any_cors_domain'] = FALSE;
$config['allowed_cors_origins'] = [];

应用/配置/ autoload.php

$autoload['libraries'] = array('database');

控制器/ API / Key.php

defined('BASEPATH') OR exit('No direct script access allowed');
require APPPATH . '/libraries/REST_Controller.php';
class Key extends REST_Controller {

    protected $methods = [
            'index_put' => ['level' => 10, 'limit' => 10],
            'index_delete' => ['level' => 10],
            'level_post' => ['level' => 10],
            'regenerate_post' => ['level' => 10],
        ];
    public function index_put()
    {
        $key = $this->_generate_key();
        $level = $this->put('level') ? $this->put('level') : 1;
        $ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1;
        if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits]))
        {
            $this->response([
                'status' => TRUE,
                'key' => $key
            ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
        }
        else
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Could not save the key'
            ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
        }
    }
    public function index_delete()
    {
        $key = $this->delete('key');
        if (!$this->_key_exists($key))
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Invalid API key'
            ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
        }
        $this->_delete_key($key);
        $this->response([
            'status' => TRUE,
            'message' => 'API key was deleted'
            ], REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code
    }
    public function level_post()
    {
        $key = $this->post('key');
        $new_level = $this->post('level');
        if (!$this->_key_exists($key))
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Invalid API key'
            ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
        }
        if ($this->_update_key($key, ['level' => $new_level]))
        {
            $this->response([
                'status' => TRUE,
                'message' => 'API key was updated'
            ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
        }
        else
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Could not update the key level'
            ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
        }
    }
    public function suspend_post()
    {
        $key = $this->post('key');
        if (!$this->_key_exists($key))
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Invalid API key'
            ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
        }
        if ($this->_update_key($key, ['level' => 0]))
        {
            $this->response([
                'status' => TRUE,
                'message' => 'Key was suspended'
            ], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
        }
        else
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Could not suspend the user'
            ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
        }
    }
    public function regenerate_post()
    {
        $old_key = $this->post('key');
        $key_details = $this->_get_key($old_key);
        if (!$key_details)
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Invalid API key'
            ], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
        }
        $new_key = $this->_generate_key();
        if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits]))
        {
            $this->_update_key($old_key, ['level' => 0]);

            $this->response([
                'status' => TRUE,
                'key' => $new_key
            ], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
        }
        else
        {
            $this->response([
                'status' => FALSE,
                'message' => 'Could not save the key'
            ], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
        }
    }
    private function _generate_key()
    {
        do
        {
            $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
            if ($salt === FALSE)
            {
                $salt = hash('sha256', time() . mt_rand());
            }

            $new_key = substr($salt, 0, config_item('rest_key_length'));
        }
        while ($this->_key_exists($new_key));

        return $new_key;
    }
    private function _get_key($key)
    {
        return $this->db
            ->where(config_item('rest_key_column'), $key)
            ->get(config_item('rest_keys_table'))
            ->row();
    }

    private function _key_exists($key)
    {
        return $this->db
            ->where(config_item('rest_key_column'), $key)
            ->count_all_results(config_item('rest_keys_table')) > 0;
    }

    private function _insert_key($key, $data)
    {
        $data[config_item('rest_key_column')] = $key;
        $data['date_created'] = function_exists('now') ? now() : time();

        return $this->db
            ->set($data)
            ->insert(config_item('rest_keys_table'));
    }

    private function _update_key($key, $data)
    {
        return $this->db
            ->where(config_item('rest_key_column'), $key)
            ->update(config_item('rest_keys_table'), $data);
    }

    private function _delete_key($key)
    {
        return $this->db
            ->where(config_item('rest_key_column'), $key)
            ->delete(config_item('rest_keys_table'));
    }

}

(控制器中用于生成Api密钥的方法)

private function _generate_key()
    {
    do
    {
        // Generate a random salt
        $salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);

        // If an error occurred, then fall back to the previous method
        if ($salt === FALSE)
        {
            $salt = hash('sha256', time() . mt_rand());
        }

        $new_key = substr($salt, 0, config_item('rest_key_length'));
    }
    while ($this->_key_exists($new_key));

    return $new_key;
    }

    private function _key_exists($key)
    {
    return $this->db
        ->where(config_item('rest_key_column'), $key)
        ->count_all_results(config_item('rest_keys_table')) > 0;
    }

在数据库中,我在app_limits表中有两个额外的表app_logsapikeymy_users列以及varchar(40),所有人都可以帮我解决问题问题,我做错了什么?

1 个答案:

答案 0 :(得分:2)

我自己找到了答案,我只是修改这些变量帮助了我:

$config['auth_override_class_method_http']['user']['customer_register']['post'] = 'none';
$config['auth_override_class_method_http']['user']['customer_login']['post'] = 'none';

这些基本上是Api键的异常方法,可以注册和登录,非常感谢