codeigniter - REST 用户注册并通过 Api Key 登录

标签 codeigniter rest codeigniter-3 codeigniter-restserver

我对 codeignitor 并不陌生,但我仍然没有使用它们称为“API key ”身份验证的功能。

我想做什么?

  • my_users 表中注册用户,并且有 apikey 作为用户注册时应存储和生成唯一 api 的列。
  • 登录用户,用户提供用户名、密码,如果提供正确的信息,它会获得登录时的响应,并在 my_users 表中使用其各自的 apikey
  • 登录后,我想使用 apikey 进行所有其他与用户相关的调用,例如 bookATask , header 为 X-API-KEY ,这将允许我控制用户 session 客户端以及安全登录和签名系统。

设置问题:

  • 每次我请求传递X-API-KEY时都会被问到,这是错误的,因为User<中可能有调用register_post/code> 注册用户和 Api key 的 Controller 不能在 header 中传递,除非它是在此方法中生成的,对吗?
  • 我每次调用电话时都会收到 status:FALSE 和 error:Invalid Api key 的信息。

我在做什么?

(仅更改代码)

application/config/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'] = [];

application/config/autoload.php

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

controllers/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'));
    }

}

( Controller 中用于生成 Api key 的方法)

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_limitsapp_logsapikey 列,其中 my_users 包含 varchar(40)表就是这样,任何人都可以帮我解决我的问题吗,我做错了什么?

最佳答案

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

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

这些基本上都是Api key的异常方法,可以注册登录,谢谢我自己

关于codeigniter - REST 用户注册并通过 Api Key 登录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40328588/

相关文章:

jquery - 使用 CodeIgniter (Active Record) 从数据库自动完成

ios - 带有网络管理面板的移动应用程序

rest - 在 Steam Web API 上设置语言

php - codeigniter 数据传递 controller->library->view

php 标签系统 - 如果标签已存在于表中

php - 错误号 : 1064 CodeIgniter query builder

php - 使用 jquery 的一页 Codeigniter 站点? Ajax ?

javascript - 数据表上的范围日期搜索 (CodeIgniter)

php - 多部分请求时 Fosrestbundle 主体为空

php - 在reactJS中如何避免使用表单返回空数据?还要检查后端代码,专家给我答案