如何从 jqgrid 发送 CSRF 令牌

Posted

技术标签:

【中文标题】如何从 jqgrid 发送 CSRF 令牌【英文标题】:How to send CSRF Token from jqgrid 【发布时间】:2021-04-03 00:31:17 【问题描述】:

我正在使用 php 7、Cake、JQuery 和 JQGrid 4.4.0 创建/编辑表格。

表格以正确的数据正确显示。

表的正确行为是这样的:

    表格与数据一起显示 我通过点击选择了表格中的一个数据行 我按下一个按钮以显示带有所选行信息的模式 我修改了模态中的任何数据 我按下保存按钮 数据保存正确

但是,当我按下保存按钮时,我收到了一个无效或不存在的 CSRF 令牌的错误。

原来表是这样定义的:

$("#tabla_tx").jqGrid(  
    autowidth: true,            
    colNames:['idProyecto','IdMovil','Nombre Movil', 'Comuna', 'Region','ZONA','Area','Proyecto','Año Proyecto',
              'Estado Plan', 'Sub-Estado Plan','BW Plan','Estado (Movil)','OTT','Estado OTT','BW OTT','PEP OTT',
              'Imputación OTT','Fecha Est30','Año Est30','Mes Est30', 'Week Est30','Tipo de Acceso',
              'Nombre Resp. Control','Prioridad', 'Fecha Entrega Parcial','Año Entrega Parcial',
              'Mes Entrega Parcial','Week Entrega Parcial','WPlan','WFET','BW Entrega','Fecha Entrega','Ano Entrega',
              'Mes Entrega','Week Entrega', 'Responsable (UC)','Condicion Actual (Problema)','Problema (Nombre Resp.)',
              'Responsable Actual (Unidad Responsable)','Gerencia Resp','Nuevo Responsable',
              'Descripcion Condicion Actual','FET Hito','Comentario','Supervisor UM',
              'Contratista','OPR1','Salto1','TICKET1','OPR2','Salto2','TICKET2','Ticket Instalacion 1',
              'Ticket Instalacion 2','Ticket Retiro 1','Ticket Retiro 2','Ticket Router','BW Actual',
              'Observacion 1','Observacion 2','Actividad a Ejecutar','Nuevo PE','Cambio de PE','PE.Actual','PE.Final',
              'Shelf','Slot','Tipo de tarjeta','SIUs','RFI Formalizado','RFI Estado','Ticket Tx',
              'Plan','Tecnologia','Activ.Infraestructura','Numero TP','Estado TP','Fecha TP','PM',
              'FET','% Avance Semana Actual', 'Ingenieria (20%)', 'Permisos (20%)', 'Instalacion Acceso (20%)', 
              'Equipos TX (20%)', 'Pruebas y PEM (20%)'],       
    colModel :[
        name:'dato0', 
        index:'dato0' ,
        align: 'left',  
        hidden:true,  
        editable: true, 
        editoptions:visible: false,
                name:'dato1', index:'dato1' ,   align: 'left',  hidden:false,  editable: true, editoptions:disabled: false, 
                 style: "width: 250px",
                name:'dato2', index:'dato2' ,   align: 'left',  hidden:false,  width: 250, editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato3', index:'dato3' ,   align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_comunas,
                name:'dato4', index:'dato4' ,   align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:disabled: true,style: "width: 250px",value:datos_region,
                name:'dato5', index:'dato5' ,   align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:disabled: true,style: "width: 250px",value:datos_zonas,
                name:'dato86', index:'dato86' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato6', index:'dato6' ,   align: 'left',  hidden:false,  width: 250, editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_proyectos,
                name:'dato7', index:'dato7' ,   align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_anos,
                name:'dato8', index:'dato8' ,   align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_estadoplan,
                name:'dato9', index:'dato9' ,   align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_subestadoplan,
                name:'dato10', index:'dato10' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato11', index:'dato11' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_estadomovil,
                name:'dato12', index:'dato12' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato13', index:'dato13' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_estadoott,
                name:'dato14', index:'dato14' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato76', index:'dato76' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato77', index:'dato77' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato22', index:'dato22' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                              dataInit: function(element) $(element).datepicker(dateFormat: 'yy-mm-dd'),
                name:'dato23', index:'dato23' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato24', index:'dato24' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true, style: "width: 250px",
                name:'dato25', index:'dato25' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",                                                    
                name:'dato21', index:'dato21' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_tipoacceso,
                name:'dato28', index:'dato28' , align: 'left',  hidden:false,  width:250, editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_responsablecontrol,
                name:'dato67', index:'dato67' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_prioridad,
                name:'dato29', index:'dato29' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                              dataInit: function(element) $(element).datepicker(dateFormat: 'yy-mm-dd'),
                name:'dato30', index:'dato30' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato31', index:'dato31' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato32', index:'dato32' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato68', index:'dato68' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato20', index:'dato20' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato15', index:'dato15' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato16', index:'dato16' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                              dataInit: function(element) $(element).datepicker(dateFormat: 'yy-mm-dd'),
                name:'dato17', index:'dato17' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato18', index:'dato18' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",
                name:'dato19', index:'dato19' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true,style: "width: 250px",                   
                name:'dato33', index:'dato33' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato26', index:'dato26' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_problema,
                name:'dato35', index:'dato35' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_nombreresponsable,
                name:'dato27', index:'dato27' , align: 'left',  hidden:false,  width:250, editable: true, edittype:'select', 
                 editoptions:disabled: true,style: "width: 250px",value:datos_unidadresponsable,
                name:'dato34', index:'dato34' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:disabled: true,style: "width: 250px",value:datos_gerenciaresponsable,
                name:'dato52', index:'dato52' , align: 'left',  hidden:false,  width:250, editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato53', index:'dato53' , align: 'left',  hidden:false,  width:300, editable: true,edittype:"textarea", 
                 editoptions:rows:"3",cols:"20",style: "width: 250px",
                name:'dato54', index:'dato54' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato55', index:'dato55' , align: 'left',  hidden:false,  width:300, editable: true,edittype:"textarea", 
                 editoptions:rows:"3",cols:"20",style: "width: 250px",
                name:'dato63', index:'dato63' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_supervisorum,
                name:'dato64', index:'dato64' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_contratista,
                name:'dato36', index:'dato36' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato37', index:'dato37' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato38', index:'dato38' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato39', index:'dato39' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato40', index:'dato40' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato41', index:'dato41' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato42', index:'dato42' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato43', index:'dato43' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato44', index:'dato44' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato45', index:'dato45' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato46', index:'dato46' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato47', index:'dato47' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px", value:datos_banda,
                name:'dato48', index:'dato48' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato49', index:'dato49' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato50', index:'dato50' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato51', index:'dato51' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px", value:datos_pe,
                name:'dato59', index:'dato59' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_cambiope,
                name:'dato60', index:'dato60' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px", value:datos_pe,
                name:'dato61', index:'dato61' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px", value:datos_pe,
                name:'dato56', index:'dato56' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato58', index:'dato58' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_slot,
                name:'dato57', index:'dato57' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_tipotarjeta,
                name:'dato62', index:'dato62' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_sius,
                name:'dato65', index:'dato65' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                              dataInit: function(element) $(element).datepicker(dateFormat: 'yy-mm-dd'),
                name:'dato69', index:'dato69' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_rftestado,
                name:'dato66', index:'dato66' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato70', index:'dato70' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_plan,
                name:'dato71', index:'dato71' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_tecnologia,
                name:'dato72', index:'dato72' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_actividad_infraestructura,
                name:'dato73', index:'dato73' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                name:'dato74', index:'dato74' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_estado_tp,
                name:'dato75', index:'dato75' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                              dataInit: function(element) $(element).datepicker(dateFormat: 'yy-mm-dd'),
                name:'dato78', index:'dato78' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:disabled: true, style: "width: 250px",
                name:'dato79', index:'dato79' , align: 'left',  hidden:false,  editable: true, 
                 editoptions:style: "width: 250px",
                              dataInit: function(element) $(element).datepicker(dateFormat: 'yy-mm-dd'),
                name:'dato80', index:'dato80' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_porcentajes,
                name:'dato81', index:'dato81' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_porcentajes,
                name:'dato82', index:'dato82' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_porcentajes,
                name:'dato83', index:'dato83' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_porcentajes,
                name:'dato84', index:'dato84' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_porcentajes,
                name:'dato85', index:'dato85' , align: 'left',  hidden:false,  editable: true, edittype:'select', 
                 editoptions:style: "width: 250px",value:datos_porcentajes
    ],
    jsonReader:  repeatitems: false ,
    paging: true,
    loadonce:false,
    pager:jQuery('#pager_tx'),
    datatype: "jsonstring",             
    datastr: data,
    rowNum: 50,
    rowList: [50,100,500,1000,5000],
    viewrecords: true,  
    caption: 'Proyectos de Transmisión e Inbuilding - SubGerencia de Proyectos de Acceso', 
    editurl:$("#urlActualizar").val().replace("param", area),
    height: '410'
);
jQuery("#tabla_tx").jqGrid('navGrid','#pager_tx',del:false,add:false,edit:false,search:false);
jQuery("#tabla_tx").jqGrid('filterToolbar',stringResult: true,searchOnEnter : false); 
jQuery("#tabla_tx").jqGrid('navButtonAdd','#pager_tx',caption:"Excel", 
    onClickButton:function() 
        $(location).attr('href',$("#urlExcel").val()); 
    
);  

根据How to pass csrf_token to the post params of editurl of jqgrid? 和passing csrf token through jqgrid on cell edit 中解释的解决方案,我在 jqGrid 的选项中添加了以下代码行,但无济于事:

loadBeforeSend: function(jqxhr)
    jqxhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrfToken"]').attr('content'));
,
editData: 
    csrfmiddlewaretoken: $('meta[name="csrfToken"]').attr('content')
,
postData: 
    csrfmiddlewaretoken: $('meta[name="csrfToken"]').attr('content')
,
ajaxEditOptions:
    beforeSend: function(jqxhr)
        jqxhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrfToken"]').attr('content'));
    
,
ajaxGridOptions:
    beforeSend: function(jqxhr)
        jqxhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrfToken"]').attr('content'));
    
,
ajaxRowOptions:
    beforeSend: function(jqxhr)
        jqxhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrfToken"]').attr('content'));
    
,
ajaxSelectOptions:
    beforeSend: function(jqxhr)
        jqxhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrfToken"]').attr('content'));
    
   

我的问题是:

    为了避免这个问题,我必须添加/更改什么吗? 在提到的页面上,有人用以下代码行解决了同样的问题。这些是否适用于我的问题?
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://www.trirand.com/jqgridwiki/doku.php?id=wiki:events#list_of_events,如果不是 beforeSend,建立 CSRF 令牌的正确事件是什么?

提前致谢

【问题讨论】:

【参考方案1】:

已解决

根据Horst Walter 在How to set request header to the ajax object for jqGrid 中的解决方案,您必须使用JQuery 的ajaxSetup 函数在带有jqgrid 表的页面中添加以下javascript 代码行:

var csrfHeader=""; //Your CSRF header here
$.ajaxSetup(
    headers : 
        'X-CSRF-Token' : csrfHeader
    
);

在我的例子中,我将标题放在页面中的 <meta> 标记中。对于像我这样使用 cakephp 4 的 PHP 的人,可以在页面的 <head> 部分添加以下行:

<?= $this->html->meta('csrfToken', $this->request->getAttribute('csrfToken')) ?>

然后将&lt;meta&gt;标签的值赋给javascript变量。对于那些使用 JQuery 的人,可以使用以下行:

var csrfHeader=$('meta[name="csrfToken"]').attr('content');

还是谢谢 :-D

【讨论】:

以上是关于如何从 jqgrid 发送 CSRF 令牌的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Postman REST 客户端发送 spring csrf 令牌?

如何从Postman休息客户端发送spring csrf令牌?

如何将 CSRF 令牌从 AngularJS 前端发送到 Spring REST 服务后端?

如何生成和验证 csrf 令牌

当 POST 是唯一方法时,如何使用 jQuery 从标头中检索 csrf 令牌?

如何忽略发送到 Django REST 框架的 CSRF 令牌?