我对 codeignitor 并不陌生,但我仍然没有使用它们称为“API 密钥”身份验证的功能。
我想做的事 ?
my_users在表中注册一个用户,并且在用户注册时有一个apikey列应该存储和生成唯一的 api。- 登录用户,用户提供用户名,密码,如果提供正确的信息,它会得到登录的响应,并
apikey在my_users表中分别列出。 - 登录后,我想将 apikey 用于所有其他与用户相关的调用
bookATask,例如 header asX-API-KEY,这将允许我在客户端控制用户会话并保护登录和签名系统。
设置中的问题:
- 每次我发出传递请求时都会被问到
X-API-KEY这是错误的,因为控制器中可能存在注册用户的调用register_post,User并且 Api 密钥不能在标头中传递,除非它是在此方法中生成的,对吗? - 我只是得到 status:FALSE 和 error:
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_logs和表中apikey带有 varchar(40) 的my_users列,任何人都可以帮我解决我的问题,我做错了什么?