这个错误是刚学习Laravel的时候碰到的,只是当时还没开始写博客,一直也没记录下来,今天下午又碰到了这个问题,趁着这会儿没啥事,赶紧总结下。

一、为什么报这个错误

答:这是由于laravel框架自带的csrf_token防护中间件的原因。这个中间件的位置在/app/middleware/VrifyCsrfToken.php。这个中间件的作用就是为了过滤Post请求。

Laravel自动为每个用户Session生成了一个CSRF Token,该Token可用于验证登录用户和发起请求者是否是同一人,如果不是则请求失败。Laravel提供了一个全局帮助函数csrf_token(本地存放在D:\www\laravel5.1\vendor\laravel\framework\src\Illuminate\Foundation\helpers.php)来获取该Token值。

二、什么是csrf防护

CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSRF或者XSRF,是一种对网站的恶意利用。尽管听起来像跨站脚本(XSS),但它与XSS非常不同,XSS利用站点内的信任用户,而CSRF则通过伪装来自受信任用户的请求来利用受信任的网站。与XSS攻击相比,CSRF攻击往往不大流行(因此对其进行防范的资源也相当稀少)和难以防范,所以被认为比XSS更具危险性。

从我们程序员的角度来看的话,请参考下面这个链接:
http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html

三、如果避免这个错误。

1、在post方式提交表单的时候,加上laravel自带的全局帮助函数csrf_token。

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

这段代码的意思是在提交表单的时候,会自动带上laravel生成的csrf_token()的值,然后在访问路由的时候,laravel会判断这个值,失败则报错:TokenMismatchException,成功则正常访问路由。

2、如果进行ajax的post请求的时候并没有提交form,表单,此时我们可以通过在meta中写入一些属性来金星csrf防护。

<head><title>Laravel</title><meta name="csrf-token" content="{{ csrf_token() }}"></head>

在ajax中,我们需要加上header属性:

 $.ajax({headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},url: "{{url('/rsa_post')}}",type: "post",dataType: "json",

这样,我们就可以正确的访问路由了。

以上两种方法我都试了一下,绝对是没问题的,可以有效的避免错误。

四、当我们不想启用框架自带的csrf防护的时候

进入:laravel/app/Middleware/VerifyCsrfToken.php
1、找到csrf的中间件,然后可以按照我下面的代码来修改

 public function handle($request, Closure $next){// 使用CSRFreturn parent::handle($request, $next);// 禁用CSRF//return $next($request);}

当使用CSRF的时候,选用上面的代码。当禁用的时候,选用下面的代码。

2、有的时候我们既需要开启CSRF防护,又需要在一些特性的post请求时不带csrf_token(),怎么办?

答:laravel框架为我们提供了一个特殊的属性,如下所示:

class VerifyCsrfToken extends BaseVerifier
{/*** The URIs that should be excluded from CSRF verification.** @var array*/protected $except = [//'upload','rsa_post',];
/*  public function handle($request, Closure $next){// 使用CSRFreturn parent::handle($request, $next);// 禁用CSRF//return $next($request);}*/
}

这段代码的意思是利用except来进行路由过滤。在我们except来进行路由过滤。在我们except中的是我们不想被防护的路由名称。此处的’upload’和’rsa_post’,都是我需要post方式访问的路由。大家可以自己试一下,经过测试,这种方式是完全没问题的。

五、laravel实现CSRF防护的源代码解析。

1、源代码位置:
      由中间件中的代码可知,laravel是通过中间件的handle()方法进行防护的。有IDE的同学可以直接追踪下该函数。没有用IDE编辑器的同学可以通过一定的路径来访问源码。
路径:laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCrsfToken.php
源码如下:

 public function handle($request, Closure $next){if ($this->isReading($request) ||$this->runningUnitTests() ||$this->shouldPassThrough($request) ||$this->tokensMatch($request)) {return $this->addCookieToResponse($request, $next($request));}throw new TokenMismatchException;}

这里大家可以根据源码中的几个方法来了解laravel的防护机制

2、源码分析:

1)首先Laravel开启Session时会生成一个token值并存放在Session中(Illuminate\Session\Store.php第90行start方法),对应源码如下:

public function start()
{// 读取session$this->loadSession();if (! $this->has('_token')) {$this->regenerateToken();}return $this->started = true;
}

2)然后重点分析VerifyToken中间件的handle方法,该方法中先通过isReading方法判断请求方式,如果请求方法是HEAD、GET、OPTIONS其中一种,则不做CSRF验证;

3)再通过shouldPassThrough方法判断请求路由是否在$excpet属性数组中进行了排除,如果做了排除也不做验证;

4)关于这个runningUnitTests()方法,我也不太明白这个是干嘛的。后来通过百度,大致知道了这个函数是为了检测laravel项目的运行环境的。如果是’cli’启动的话,则正常。

5)最后通过tokensMatch方法判断请求参数中的CSRF TOKEN值和Session中的Token值是否相等,如果相等则通过验证,否则抛出TokenMismatchException异常。

对应源码如下:

public function handle($request, Closure $next)
{if ($this->isReading($request) || $this->shouldPassThrough($request) || $this->tokensMatch($request)) {return $this->addCookieToResponse($request, $next($request));}throw new TokenMismatchException;
}

以上都是laravel关于CSRF防护的内容。果然不懂的时候看源码才是王道啊。

end

laravel报错:TokenMismatchException in VerifyCsrfToken.php相关推荐

  1. 部署laravel报错:No supported encrypter found. The cipher and / or key length are invalid.

    一.背景 把laravel项目部署到服务器上.访问时候,报错信息为: No supported encrypter found. The cipher and / or key length are ...

  2. PHP Laravel报错No application encryption key has been specified

    故障现象 PHP Laravel项目报错No application encryption key has been specified 原因 出现此问题的原因是:没有设置应用程序加密密钥 解决方法 ...

  3. 如果Laravel 报错 file_put_contents(): failed to open stream

    问题解决方法 执行命令 php artisan cache:clear 并赋予 /storage 文件夹读写权限: chmod -R 777 storage: 若在执行 php artisan cac ...

  4. laravel报错:MassAssignmentException

    报这种错误是因为没有设置白名单或者黑名单.在使用fill填充时,需要设置白/黑名单. $model->fill($params);return $model->save(); 找到对应的m ...

  5. Laravel 报错 failed to open stream 的解决方法

    1. 问题解决方法 执行命令 php artisan cache:clear 并赋予 /storage 文件夹读写权限: chmod -R 777 storage:若在执行 php artisan c ...

  6. Laravel 报错 file_put_contents(): failed to open stream......解决

    安装完laravel,启动完后报 ErrorException (E_WARNING) file_put_contents(/www/wwwroot/blog/storage-错误,是因为权限原因导致 ...

  7. Laravel报错:ErrorException (E_ERROR) Route [*] not defined.

    问题介绍: 使用环境:laravel58 我想使用资源管理器进行跳转,路由代码如下: Route::group(['namespace'=>'Admin','prefix'=>'admin ...

  8. Valet安装laravel报错

    Valet安装错误指南 valet command not found mysql command not found laravel command not found valet command ...

  9. Laravel 报错 file_put_contents(): failed to open stream 的解决方法

    2019独角兽企业重金招聘Python工程师标准>>> 问题解决方法(框架在运行过程中会产生很多的临时文件) 执行命令 php artisan cache:clear 并赋予 /st ...

最新文章

  1. 读书笔记--C陷阱与缺陷(三)
  2. 小程序之 转发/分享
  3. 如何阅读学术论文、聆听学术报告 —— 叶志明
  4. android XMl 解析神奇xstream 二: 把对象转换成xml
  5. 这五个网站可以让你免费学习编程,快收藏!
  6. VTK:图片之ImageHistogram
  7. 以后所有经济时事的点评都不在这里
  8. 油耗虚高保养贵,便宜车就活该问题多多?
  9. 凤凰刷机软件连接不上手机的解决办…
  10. 基于javaweb的银行柜员绩效考核系统
  11. SSM面试题,2021最新Java面试题及答案
  12. [浅析]UE4关卡流
  13. Navicat备份sqlserver数据库
  14. 使用 Parity 建立Proof-of-Authority (PoA) Ethereum Chain
  15. 【漆天编程】MT4和MT5有什么区别?这是我见到过的最好的回答
  16. 人工智能基础之美女和野人过河问题
  17. 斐讯n1刷鸿蒙系统,【总结】在N1上面成功刷入armbian并启动的步骤
  18. c语言函数定义时涉及的基本要素是什么,C语言基础:函数的定义与调用
  19. 毕业论文-----有关目录的全部问题
  20. aria2c指定下载存储路径的一个问题(可能不算bug)

热门文章

  1. ‘torch.nn‘ has no attribute ‘SiLU‘
  2. 动态slimmable网络:高性能的网络轻量化方法!对比slimmable涨点5.9%
  3. [WinError 17] 系统无法将文件移到不同的磁盘驱动器
  4. win10之dlib安装 c++调用
  5. F-Strings:超级好用的Python格式字符串!!
  6. pybind11回调函数返回指针
  7. exception: access violation reading 0xFFFFFFFFFFFFFFFF
  8. opencv bug 合集
  9. 基于GPUImage的多滤镜rtmp直播推流
  10. ios10申请权限以及弹出允许使用数据框