开发笔记📐 发现👽 人物👮 趣闻💦
Laravel Ajax或表单实现Post/Get等请求实战注意CsrfToken

Laravel Ajax或表单实现Post/Get等请求实战注意CsrfToken
2018-05-25 17:10:48   点击:

Laravel框架为用户项目的安全性做了充分的考虑,不仅在用户认证上提供了方便的auth guard,针对经常被挖掘的CSRF漏洞,laravel在请求认证方面,也提供了严格的CSRF Token机制,以验证登录用户和发起请求者是否是同一人,如果不是则请求失败。

不过优秀的安全性也会经常为新手带来困扰,以前使用的Ajax突然报错,或者简单的表单POST请求无法提交。老九从个人笔记和网上总结了一些常见问题的解决方案如下:

1. Laravel ajax请求 419错误

错误解决办法在页面上添加 

<meta name="csrf-token" content="{{ csrf_token() }}"> 

然后在页面的script标签中添加 

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

2. post提交数据时候显示如下:The page has expired due to inactivity. Please refresh and try again

这是由于在laravel框架中有此要求:任何指向 web 中 POST, PUT DELETE 路由的 HTML 表单请求都应该包含一个 CSRF 令牌,否则,这个请求将会被拒绝。

在表单内添加语句{{ csrf_field() }}即可。

3. 通用方法:

Laravel提供了一个全局帮助函数csrf_token来获取该Token值,因此只需在视提交图表单中添加如下HTML代码即可在请求中带上Token:

<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">

该段代码等同于全局帮助函数csrf_field的输出:

<?php echo csrf_field(); ?>

在Blade模板引擎中还可以使用如下方式调用:

{!! csrf_field() !!}

如果使用Ajax提交POST表单,又该如何处理呢?我们可以将Token设置在meta中:

<meta name="csrf-token" content="{{ csrf_token() }}">

然后在全局Ajax中使用这种方式设置X-CSRF-Token请求头并提交:

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

Laravel的VerifyCsrfToken中间件会检查X-CSRF-TOKEN请求头,如果该值和Session中CSRF值相等则验证通过,否则不通过。

4. 静态页面或者不需要验证的环境如何解决POST请求无法提交的问题

有的时候我们需要静态页面来提供请求,这涉及一些需要CDN的环境。另外并不是所有请求都需要避免CSRF攻击,比如去第三方API获取数据的请求。

可以通过在VerifyCsrfToken(app/Http/Middleware/VerifyCsrfToken.php)中间件中将要排除的请求URL添加到$except属性数组中:

<?php

    namespace App\Http\Middleware;

    use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;

    class VerifyCsrfToken extends BaseVerifier
    {
        /**
         * 指定从 CSRF 验证中排除的URL
         *
         * @var array
         */
        protected $except = [
            'testCsrf'
        ];
    }

PHP laravel Ajax CSRF

上一篇:阿里云UBUNTU16.04开启外部访问MYSQL3306端口方法记录
下一篇:Laravel使用 Artisan命令make:migration的一些细节