Codeigniter AJAX CSRF protection



我在后端使用codeigniter。

最近,我听说了"CSRF"一词,并决定保护这些请求。

我的网站上几乎所有的操作都是通过Ajax&有时我使用DOM操作创建/附加页面内容[这里有疑问,我如何将CSRF令牌注入视图文件?]

Okkey,在那之后我该如何验证?

假设我将这些值作为令牌添加并传递给服务器,那么我可以使用构造函数来检查&验证这一点?

例如:

Class Cl_Controller extends Ci_controller
{
  function __construct()
 {
    //loading libraries,models,helpers etc...
    if (isset($this->input->get_post("CSRF_TOKEN")) || _another_condition_)
    {
        // The CSRF TOKEN is invalid or null ,the action cannot be done...
    }
 }
 function register()
 {
  //some codes...
 } 
 function delete_user()
 {
   //some codes
 }
}

有可能做一些事情把这个联系起来吗?

请给我一些好主意;通常的做法。

谢谢。

对于我的ajax调用,我通常执行两次检查;

确保它是一个ajax请求,使用一个小的帮助文件。

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('ajax_check')) {
    /**
     * Check AJAX
     * 
     * Checks to see if you (or the royal I) are dealing with an AJAX call.
     * 
     * @return boolean
     */
    function ajax_check() {
        if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
            return TRUE;
        } else {
            show_404();
            return FALSE;
        }
    }
}
if ( ! function_exists('ajax_response')) {
    /**
     * JSON Response Wrapper
     * 
     * Wraps up any data nicely for sending back to an ajax call
     *
     * @return  string
     */
    function ajax_response($status, $data) {
        if (!is_array($data)) {
            $data = array();
        }
        // Set the JSON header appropriately
        header('Content-Type: application/json');
        // Echo out the array into json
        echo json_encode(array_merge(array('status' => $status), $data));
        exit;
    }
}
if ( ! function_exists('ajax_force_fail')) {
    /**
     * Force AJAX Failure
     * 
     * If you ever need to, force an AJAX to fail
     */
    function ajax_force_fail() {
        $_ci =& get_instance();
        $_ci->output->set_status_header(500);
    }
}

用法类似;

public function some_function() {
    $this->load->helper('ajax');
    ajax_check();
    try {
        // do something
        ajax_response('success', array('data' => $some_var));
    } catch (Exception $e) {
        ajax_response('failure', array('data' => $e->getMessage()));
    }
}

和xsrf类似的方法。文件:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('xsrf_get_token')) {
    /**
     * Get XSRF Token
     * 
     * Returns a token that exists for one request that verifies that
     * the action was executed by the person that requested it
     *
     * @return  string
     */
    function xsrf_get_token() {
        $ci =& get_instance();
        if ($ci->session->userdata('xsrf_hash')) {
            $token = $ci->session->userdata('xsrf_hash');
        } else {
            // Generate the token
            $token = sha1(microtime().$ci->uri->uri_string());
            // Set it in the session
            $ci->session->set_userdata('xsrf_hash', $token);
        }
        //Return it
        return $token;
    }
}
if ( ! function_exists('xsrf_get_token_field')) {
    /**
     * Get XSRF Token Field
     * 
     * Returns an xhtml form element to include xsrf token.
     * You can specify the id/name attribute of the input.
     * Has a dependancy to get_xsrf_token().
     *
     * @param   string  The id/name to be used
     * @return  string
     */
    function xsrf_get_token_field($name='auth_token') {
        return '<input type="hidden" id="'.$name.'" name="'.$name.'" value="' .xsrf_get_token(). '" />';
    }
}
if ( ! function_exists('xsrf_delete_token')) {
    /**
     * Delete XSRF Token
     * 
     * Deletes the xsrf token
     *
     * @return  boolean
     */
    function xsrf_delete_token() {
        $ci =& get_instance();
        if ($ci->session->userdata('xsrf_hash')) {
            $ci->session->unset_userdata('xsrf_hash');
            return TRUE;
        } else {
            return FALSE;
        }
    }
}
if ( ! function_exists('xsrf_check_token')) {
    /**
     * Get XSRF Token Field
     * 
     * Checks that the token is still valid, returns true if so. 
     * Deletes old token after valid or fail.
     * Has a dependacy to xsrf_delete_token()
     *
     * @param   string  The challenge token
     * @return  boolean
     */
    function xsrf_check_token($challenge_token) {
        // CI
        $ci =& get_instance();
        // Get the stored token
        $token = $ci->session->userdata('xsrf_hash');
        // Delete the old token
        xsrf_delete_token();
        // Returns if the token is the right token
        return ($token == $challenge_token);
    }
}

用途(控制器);

public function some_other_function() {
    $this->form_validation->set_rules('username', 'Username', 'required|callback_check_token');
    if($this->form_validation->run() == TRUE ) {
        // do something
    } else {
        // something else
    }
}
// callback function
public function check_token($val) {
    if (xsrf_check_token($val) == TRUE) {
        return TRUE;
    } else {
        $this->form_validation->set_message('check_token', 'Oops');
        return FALSE;
    }
}

在视图中;

<form action="" method="post">
    <?php echo xsrf_get_token_field(); ?>
    ...
</form>

最新更新