Как передать csrf_token в почтовые параметры editurl jqgrid? - PullRequest
4 голосов
/ 25 июня 2011

Я использую JqGrid с фреймворком Django. Это JS:

      jQuery("#list").jqGrid({
        url:'{% url views.manage.devicesajax %}',
        datatype: 'json',
        mtype: 'GET',
        colNames:['DID', 'UDID', 'Owner', 'Name', 'First seen', 'Last seen'],
        colModel :[ 
          {name:'did', index:'did', width: 30, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'udid', index:'udid', width: 120, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_owner', index:'d_owner', width: 70, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_name', index:'d_name', editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_firstseen', index:'d_firstseen', width: 80}, 
          {name:'d_lastseen', index:'d_lastseen', width: 80}],
        pager: jQuery('#pager'),
        rowNum:20,
        rowList:[20,50,100],
        sortname: 'did',
        sortorder: "desc",
        multiselect: true,
        viewrecords: true,
        imgpath: 'themes/basic/images',
        caption: 'Devices list',
        height: 330,
        width: 1000,
        onSelectRow: function(id) {
            var id = $("#list").getRowData(id).message_id;
            message_id = id;
        },
        editurl: "{% url views.manage.deviceseditajax %}"
    });

Когда я редактирую строку в JqGrid, я получаю ошибку от editurl:

Запрещено (403) Проверка CSRF не удалась. Запрос отменен.

Это потому, что csrf_token не переходит к editurl с другими данными. Как добавить csrf_token в запрос POST для editurl?

Этот код отлично работает (полный фрагмент инициализации jqgrid):

     jQuery("#list").jqGrid({
        url:'{% url views.manage.devicesajax %}',
        datatype: 'json',
        mtype: 'GET',
        colNames:['DID', 'UDID', 'Owner', 'Name', 'First seen', 'Last seen'],
        colModel :[ 
          {name:'did', index:'did', width: 30, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'udid', index:'udid', width: 120, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_owner', index:'d_owner', width: 70, editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_name', index:'d_name', editable: true, searchoptions:{sopt:['eq','ne','bw','cn']}}, 
          {name:'d_firstseen', index:'d_firstseen', width: 80}, 
          {name:'d_lastseen', index:'d_lastseen', width: 80}],
        pager: jQuery('#pager'),
        rowNum:20,
        rowList:[20,50,100],
        sortname: 'did',
        sortorder: "desc",
        multiselect: true,
        viewrecords: true,
        imgpath: 'themes/basic/images',
        caption: 'Devices list',
        height: 330,
        width: 1000,
        editurl: "{% url views.manage.deviceseditajax %}",
    });

      jQuery("#list").navGrid('#pager',{edit:true,add:true,del:true,search:true},
        {
            closeAfterEdit:true,
            reloadAfterSubmit:true,
            closeOnEscape:true,
            editData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
        },
        {
            closeAfterAdd:true,
            reloadAfterSubmit:true,
            closeOnEscape:true,
            editData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
        }, 
        {
            closeOnEscape:true,
            delData: {csrfmiddlewaretoken: '{{ csrf_token }}'}
        }, 
        {
         caption: "Search",
         Find: "Find",
         Reset: "Reset",
         sopt  : ['eq', 'cn'],
         matchText: " match",
         rulesText: " rules",
         closeAfterSearch: true,
         afterShowSearch: function ()
         {
             $('#reset_filter1_block').show();
         }
       }
      );

Ответы [ 4 ]

3 голосов
/ 25 июня 2011

Я не использую фреймворк Django и не знаком с csrf_token, но после поиска в Google кажется, что вам нужно установить его в HTTP-заголовке запроса: xhr.setRequestHeader('X-CSRF-Token', csrf_token);.Для этого в случае jqGrid вы можете использовать loadBeforeSend обработчик событий:

loadBeforeSend: function(jqXHR) {
    // you should modify the next line to get the CSRF tocken
    // in any way (for example $('meta[name=csrf]').attr('content')
    // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
    var csrf_token = '<%= token_value %>'; // any way to get
    jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
}

См. здесь для очень близкой проблемы.

ОБНОВЛЕНО : Чтобы опубликовать дополнительные данные в случае использования редактирования формы, вы можете использовать editData: editData: {csrfmiddlewaretoken: '<% = token_value%>'}.Например:

jQuery("#list").jqGrid('navGrid','#pager',{},
    { // Edit option (parameters of editGridRow method)
        recreateForm:true,
        reloadAfterSubmit:false,
        closeOnEscape:true,
        savekey: [true,13],
        closeAfterEdit:true,
        ajaxEditOptions: {
            beforeSend: function(jqXHR) {
                // you should modify the next line to get the CSRF tocken
                // in any way (for example $('meta[name=csrf]').attr('content')
                // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
                var csrf_token = '<%= token_value %>'; // any way to get
                jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
            }
        },
        editData: {
            csrfmiddlewaretoken: '<%= token_value %>'
        }
    },
    { // Add options (parameters of editGridRow method)
        recreateForm:true,
        reloadAfterSubmit:false,
        closeOnEscape:true,
        savekey: [true,13],
        closeAfterAdd:true,
        ajaxEditOptions: {
            beforeSend: function(jqXHR) {
                // you should modify the next line to get the CSRF tocken
                // in any way (for example $('meta[name=csrf]').attr('content')
                // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
                var csrf_token = '<%= token_value %>'; // any way to get
                jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
            }
        },
        editData: {
            csrfmiddlewaretoken: '<%= token_value %>'
        }
    }
);

Я разместил здесь оба способа: установку HTTP-заголовка 'X-CSRF-Token' и публикацию параметра csrfmiddlewaretoken.Вы можете удалить один способ после соответствующих экспериментов.

Если вы используете некоторые параметры для всех сеток на странице, вы можете лучше изменить значения по умолчанию (подробности см. здесь )

jQuery.extend(jQuery.jgrid.edit, {
    recreateForm:true,
    reloadAfterSubmit:false,
    closeOnEscape:true,
    savekey: [true,13],
    closeAfterAdd:true,
    closeAfterEdit:true,
    ajaxEditOptions: {
        beforeSend: function(jqXHR) {
            // you should modify the next line to get the CSRF tocken
            // in any way (for example $('meta[name=csrf]').attr('content')
            // if you have <meta name="csrf" content="abcdefjklmnopqrstuvwxyz="/>)
            var csrf_token = '<%= token_value %>'; // any way to get
            jqXHR.setRequestHeader('X-CSRF-Token', csrf_token);
        }
    },
    editData: {
        csrfmiddlewaretoken: '<%= token_value %>'
    }
});

Эта настройка является общей для форм Add и Edit.Таким образом, вы можете использовать navGrid в упрощенном виде.

jQuery("#list").jqGrid('navGrid','#pager');
0 голосов
/ 03 апреля 2015

Я нашел простое решение, используя последние JqGrid и Inline Edit, отправив csrf_token для запроса POST django без @ csrf_exempt

onSelectRow: function(id){
     if(id && id!==lastSel){ 
        $(selector).restoreRow(lastSel); 
        lastSel=id; 
     }

     var editparameters = {
        extraparam: {csrfmiddlewaretoken: $('.token-data').data('token')},
        keys: true,
      };
     $(selector).jqGrid('editRow', id, editparameters);

}

Например, см. В моем блоге сообщение: http://yodi.polatic.me/jqgrid-inline-editing-integration-with-django-send-csrf-token/

0 голосов
/ 25 июня 2011

Согласно документации jqGrid , вы можете передать опции postData .Если вы используете плагин jQuery Cookie , вы можете добавить что-то вроде:

postData: {
    csrfmiddlewaretoken: $.cookie(CSRF_COOKIE_NAME)
},

в свой список опций в jqGrid.

CSRF_COOKIE_NAME установлен в вашемПриложение django settings.py и по умолчанию является csrftoken.

0 голосов
/ 25 июня 2011

Проверьте ваши куки. CSRF Django также сохраняет cookie csrftoken, который имеет то же значение, что и csrf_token, который вы бы использовали в форме. Вы можете использовать любую библиотеку cookie Javascript, чтобы получить cookie и передать его в запрос POST как csrfmiddlewaretoken.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...