Laravel中Ajax调用时的CSRF对策

By | 2015/11/14

我最讨厌在文章开头重复一些基础知识了…… 但是大家都这么做(-__-)b

CSRF是”cross site request forgery”的意思,简单来说就是防止恶意页面中一个简单的form提交,就向你保持了登陆状态了网站里请求做一些你不想做的事情……言尽于此,我们之间看Laravel里的CSRF相关的内容吧!

Laravel(5以后)有个默认的CSRF middleWare,所有POST,PUT请求都会经过这个middleWare,看有没有csrf的token存在并且匹配,不存在的话就会抛出错误页面。提一句,如果做微信接口的话,一定要在接口地址上把这个middleWare给去掉,因为微信大多数都是把数据POST过来的,而你不能奢望微信给你附上一个csrf_token。。。

在Laravel的表单中,埋入一个就可以在表单请求的时候发出正确的token,这样就不会有问题了,而在ajax请求的时候呢,方法多多~

1. 如果你是用ajax submit一个已经存在的form,那么就和平常一样,把csrf藏在表单里就好了,万事大吉。

2. 如果你不是提交表单,那么就要考虑将token值放在一个什么地方,比如还是一个input中,然后ajax提交的时候去读取这个input,附在提交值中。

3. 当然,token值也可以不放在提交的值中,而放在headers里,如果你的js脚本直接写在blade模板里,可以用

$.ajaxSetup({
    headers: { 'X-CSRF-TOKEN' : '{{ csrf_token() }}' }
});

来把token值提交给服务器。

4. 当然很多时候js是在静态文件里的,那么可以把token值放在html的meta里,就像这样

<meta name="_token" content="{{ csrf_token() }}"/>

这样就能用

$.ajaxSetup({
   headers: {
       'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
   }
});

5. 然而以上的方法都不够帅!!!因为你总是要在页面的什么地方调用csrf_token()输出这个值,然后用js脚本获得这个值~

我看Laravel源码的时候发现,Laravel默认会把CSRF_TOKEN的值写在一个叫XCRF-TOKEN的cookie中,其实每次访问这个值都会发生变化,那我们只要用这个值就好了嘛,下面就是见证奇迹的时刻(好古老的梗):

$.ajaxSetup({
     headers: {
         'X-XSRF-TOKEN': $.cookie('XSRF-TOKEN')
     }
});

在某个全局地方调用这个就好了,你不需要再手动输出token了(当然你要用cookie插件)!注意这里的XSRF而不是CSRF了。

8 thoughts on “Laravel中Ajax调用时的CSRF对策

    1. xishui Post author

      是指微信微博QQ空间那种分享么?我觉得我的文章和这些社交媒体上的主流文章格调不搭呀,所以就没弄……

      Reply
  1. 小白

    laravel控制中怎么接收ajax传输的数据,拜谢

    Reply
  2. JONE

    我的问题不一样,比如 表单页面长时间没提交 _toke参数会过期,那么怎么在后台判断_token过期

    Reply
    1. xishui Post author

      token似乎本身是不会过期的,要么通过登录状态来判断,要么额外输出一个隐藏的时间字段,这样后台通过这个实际来判断

      Reply
  3. Pingback: laravel ajax请求携带csrf token – 伴侣哟

发表评论

您的电子邮箱地址不会被公开。