How to : Ajax CSRF Token in Codeigniter 3 and AngularJs

By Budyks    PHP

This maybe an old issue but some developers may have this problem unresolved. Cross-site request forgery protection is important for your application thus letting this off could harm your application and let the attacker easily penetrate it. 

Codeigniter already has this feature built-in and you dont need to worry about it. 

Csrf Token Codeigniter 

All you need is just a little tweak to the core Security library as Codeigniter only allow POST method for the CSRF protection and yet in fact we can have  PUT, PATCH and DELETE method. 

Extending Security Library

Create a file named MY_Security.php inside /application/core/ and copy this code 

        // Check if URI has been whitelisted from CSRF checks
        if ($exclude_uris = config_item('csrf_exclude_uris')) {
            $uri = load_class('URI', 'core');
            if (in_array($uri->uri_string(), $exclude_uris)) {
                return $this;
        //Double submit cookie method: COOKIE needs to exist and at least either
        //POST or SERVER needs to exist and at least one of the POST or SERVER must match the COOKIE

        if (
        ) {
        //if CSRF token was in the POST, then it needs to match the cookie
        if (isset($_POST[$this->_csrf_token_name])) {
            if ($_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) {
        //if CSRF token was in the SERVER (headers), then it needs to match the cookie
        if (isset($_SERVER['HTTP_X_CSRF_TOKEN'])) {
            if ($_SERVER['HTTP_X_CSRF_TOKEN'] !== $_COOKIE[$this->_csrf_cookie_name]) {

        // We kill this since we're done and we don't want to polute the _POST array
        if (config_item('csrf_regenerate')) {
            $this->_csrf_hash = NULL; //must be null
        log_message('debug', 'CSRF token verified');

        return $this;

Update your CI 3 Config file (find these codes)

$config['csrf_protection'] = TRUE; //enabled CSRF protection
$config['csrf_token_name'] = 'csrf_test_name';
$config['csrf_cookie_name'] = 'csrf_cookie_name';
$config['csrf_expire'] = 7200;
$config['csrf_regenerate'] = TRUE;
$config['csrf_exclude_uris'] = array();

From here your codeigniter is ready to use CSRF protection but you are not for the Ajax call. In angular, generally we have to attach the CSRF Token on every ajax Call specially with POST, OUT, PATCH and DELETE http verb. We can utilize the power of Angular httpInterceptor with a little help from Angular Cookies library. 

angular.module('app', ['ngCookies'])
.factory('httpInterceptor', ['$q', '$location', '$cookies', 
   function($q, $location, $cookies) {
        return {
            request: function(config) {
                //include Token in Paylod
       = || {};
                //payload field name is: csrf_test_name
      ['csrf_test_name'] = $cookies.get('csrf_cookie_name');

                //also include token in Http header (recommended)
                config.headers['X-Csrf-Token'] = $cookies.get('csrf_cookie_name'); 
            responseError: function(response) {
                return $q.reject(response);

        return config;
.config(['$httpProvider', '$routeProvider',  
    function($httpProvider, $routeProvider) {
        //inject Interceptor

Notice that we get the Token from the Browser cookie set by Codeigniter. The cookie name is csrf_cookie_name  so we fetch the Token like this 


and the field name for the Payload is csrf_test_name   

You are done. test your configuration now and check its working properly.  Now everytime you POST, PUT, DELETE something in your application, Codeigniter will validate the csrf token and immediately invalidate it and regenerate new token for you so your next Ajax call will use different token. This approach is not for multiple ajax Call at the same time. if you have multiple ajax call (POST, PUT, DELETE) at the same time, you might need to adjust it yourself or you can just turn off the config 

$config['csrf_regenerate'] = FALSE; //dont Regenerate token on every submission

and let the token expires within specified time. Default is  7200 seconds

$config['csrf_expire'] = 7200;

but this option is less secure than the default one. You are a JQuery Fans? you can setup your Ajax like this 

    beforeSend: function(xhr, settings) {
        if (settings.type == 'POST' || settings.type == 'PUT' || settings.type == 'DELETE') {
            function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie != '') {
                    var cookies = document.cookie.split(';');
                    for (var i = 0; i < cookies.length; i++) {
                        var cookie = jQuery.trim(cookies[i]);
                        // Does this cookie string begin with the name we want?
                        if (cookie.substring(0, name.length + 1) == (name + '=')) {
                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                return cookieValue;
            if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
                // Only send the token to relative URLs i.e. locally.
                xhr.setRequestHeader("X-Csrf-Token", getCookie('csrf_cookie_name'));


    Follow Us