web-dev-qa-db-fra.com

Vérifier la demande Ajax dans CodeIgniter

Je suis dans un PHP et je veux vérifier si la demande est une demande Ajax. (Fondamentalement, pour NE PAS autoriser l'accès direct au script, autre que les appels Ajax.)

Donc, je définis IS_AJAX quelque part dans le principal index.php fichier:

define('IS_AJAX', 
       isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 
       strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');

Et puis le vérifier en haut de mon script:

if (!IS_AJAX) exit('No direct script access allowed');

Puisque je suis nouveau sur CodeIgniter, je voudrais savoir:

  • Existe-t-il une telle fonctionnalité intégrée?
  • Existe-t-il une manière plus élégante de le faire?
30
Dr.Kameleon

Vous pouvez utiliser $this->input->is_ajax_request() de la classe input :

if (!$this->input->is_ajax_request()) {
   exit('No direct script access allowed');
}
116
Yan Berk

Il n'y a pas besoin d'ajouter une if (!$this->input->is_ajax_request()) à chaque AJAX si vous utilisez - hooks (documents CI) . Ceci est basé sur la solution de Jorge ici avec quelques légères améliorations:

config/config.php

Activez les hooks CI en modifiant la valeur par défaut (de FALSE):

$config['enable_hooks'] = TRUE;

config/hooks.php

Ajoutez ce qui suit à la fin:

$hook['post_controller_constructor'] = array(
    'class' => 'Ajax_only',
    'function' => 'show_404_on_illegal_ajax',
    'filename' => 'Ajax_only.php',
    'filepath' => 'hooks'
);

post_controller_constructor : appelé immédiatement après l'instanciation de votre contrôleur, mais avant tout appel de méthode

config/ajax_methods.php

Créez un nouveau fichier de configuration avec tous les contrôleurs et méthodes qui ne doivent être invoqués que lorsqu'une demande AJAX est effectuée:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
/*
|--------------------------------------------------------------------------
| References to all AJAX controllers' methods or the controller itself
|--------------------------------------------------------------------------
|
| Based on Jorge's solution: https://stackoverflow.com/a/43484330/6225838
| Key: controller name
| Possible values:
| - array: method name as key and boolean as value (TRUE => IS_AJAX)
| - boolean: TRUE if all the controller's methods are for AJAX requests
|
*/
$config['welcome'] = [
  'index' => FALSE, // or 0 -> this line can be removed (just for reference)
  'ajax_request_method_1' => TRUE, // or 1
  'ajax_request_method_2' => TRUE, // or 1
];
$config['ajax_troller'] = TRUE;

hooks/Ajax_only.php

Créez le hook lui-même, qui détecte si le contrôleur actuel et/ou ses méthodes sont présents dans le nouveau fichier de configuration ci-dessus. Si c'est le cas, il affiche la page 404 par défaut lorsque la demande actuelle n'est pas AJAX et que la méthode/le contrôleur a une valeur véridique dans la configuration:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Ajax_only {

  public function __construct()
  {
    $this->CI = &get_instance();
    $this->CI->config->load('ajax_methods');
  }

  public function show_404_on_illegal_ajax()
  {
    $fetched_troller_val = $this->CI->config->item(
      $this->CI->router->fetch_class()
    );
    $fetched_method = $this->CI->router->fetch_method();

    $is_ajax_method = is_array($fetched_troller_val) &&
        // verify if the method's name is present
        isset($fetched_troller_val[$fetched_method]) &&
        // verify if the value is truthy
        $fetched_troller_val[$fetched_method];

    // if the controller is not in the config file then
    // config->item() returned NULL
    if($fetched_troller_val !== NULL &&
        $this->CI->input->is_ajax_request() === FALSE  &&
        ($fetched_troller_val === TRUE || $is_ajax_method)
      ) {
      show_404();
    }
  }
}
4
CPHPython

si vous souhaitez personnaliser les demandes de votre application codeigniter, essayez ceci: vous devez créer un hook nommé Ajax_only.php dans le dossier application/hooks

class Ajax_only {
    private $_controllers = [];

    private $CI;

    public function __construct() {
        $this->CI =& get_instance();
    }

    public function eval_request() {
        $controller = $this->CI->router->fetch_class();
        $method = $this->CI->router->fetch_method();
        if ( array_key_exists( $controller, $this->_controllers ) && $this->CI->input->is_ajax_request() === FALSE  ) {
            if ( ( $this->_controllers[ $controller ] === TRUE || ( is_array( $this->_controllers[ $controller ] ) && array_key_exists( $method, $this->_controllers[ $controller ] ) && $this->_controllers[ $controller ][ $method ] === TRUE ) ) ) {
                show_404();
            }
        }
    }
}


/*Examples
 * $_controllers = [
 *      'my_controller_name' => TRUE //all methods must be ajax
 *      'my_controller_name  => [
 *          'method_name' => TRUE //only the selected methods must be ajax
 *      ]
 * ]
 */

Et configurez votre fichier application/config/hooks.php

$hook['post_controller_constructor'] = array(
    'class' => 'Ajax_only',
    'function' => 'eval_request',
    'filename' => 'Ajax_only.php',
    'filepath' => 'hooks'
);
2
Jorge Andrés