- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章ThinkPHP下表单令牌错误与解决方法分析由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文实例讲述了ThinkPHP下表单令牌错误与解决方法。分享给大家供大家参考,具体如下:
在项目的开发过程中,添加、编辑数据时偶尔会遇到系统提示的“表单令牌错误”,一开始没怎么在意,直到今天下午QA把此问题提到bug系统了,正好时间也有空余,就追着TP3.13的源码看了下去,几分钟后,便知道原委了.
在项目中开启表单令牌,通常要在配置文件中做如下配置 。
1
2
3
4
5
6
7
8
|
// 是否开启令牌验证
'TOKEN_ON'
=> true,
// 令牌验证的表单隐藏字段名称
'TOKEN_NAME'
=>
'__hash__'
,
//令牌哈希验证规则 默认为MD5
'TOKEN_TYPE'
=>
'md5'
,
//令牌验证出错后是否重置令牌 默认为true
'TOKEN_RESET'
=> true
|
以编辑数据为例,通常在服务端有个Model写上字段过滤规则,Action写上数据检测的代码,如 。
1
2
3
4
|
$table
= D(
'table'
);
if
(!
$table
->create()){
exit
(
$this
->error(
$table
->getError()));
}
|
这时在IDE上双击create()定位到TP框架中Model.class.php中的create方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
/**
* 创建数据对象 但不保存到数据库
* @access public
* @param mixed $data 创建数据
* @param string $type 状态
* @return mixed
*/
public
function
create(
$data
=
''
,
$type
=
''
) {
……省略……
// 表单令牌验证
if
(!
$this
->autoCheckToken(
$data
)) {
$this
->error = L(
'_TOKEN_ERROR_'
);
return
false;
}
……省略……
}
|
看到代码会理解当autoCheckToken方法检测失败时会报错,那么就接着跟踪此方法 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 自动表单令牌验证
// TODO ajax无刷新多次提交暂不能满足
public
function
autoCheckToken(
$data
) {
// 支持使用token(false) 关闭令牌验证
// 如果在Action写了D方法,但没有对应的Model文件,那么$this->options为空
if
(isset(
$this
->options[
'token'
]) && !
$this
->options[
'token'
])
return
true;
if
(C(
'TOKEN_ON'
)){
$name
= C(
'TOKEN_NAME'
);
if
(!isset(
$data
[
$name
]) || !isset(
$_SESSION
[
$name
])) {
// 令牌数据无效
return
false;
}
// 令牌验证
list(
$key
,
$value
) =
explode
(
'_'
,
$data
[
$name
]);
if
(
$value
&&
$_SESSION
[
$name
][
$key
] ===
$value
) {
// 防止重复提交
unset(
$_SESSION
[
$name
][
$key
]);
// 验证完成销毁session
return
true;
}
// 开启TOKEN重置
if
(C(
'TOKEN_RESET'
)) unset(
$_SESSION
[
$name
][
$key
]);
return
false;
}
return
true;
}
|
看了这段代码,会发现第一个判断中有$_SESSION[$name],那么这个seesion变量时从哪里过来的呢,这还得从生成令牌时说起,定位TokenBuildBehavior.class.php文件 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
// 创建表单令牌
private
function
buildToken() {
$tokenName
= C(
'TOKEN_NAME'
);
$tokenType
= C(
'TOKEN_TYPE'
);
if
(!isset(
$_SESSION
[
$tokenName
])) {
$_SESSION
[
$tokenName
] =
array
();
}
// 标识当前页面唯一性
$tokenKey
= md5(
$_SERVER
[
'REQUEST_URI'
]);
if
(isset(
$_SESSION
[
$tokenName
][
$tokenKey
])) {
// 相同页面不重复生成session
$tokenValue
=
$_SESSION
[
$tokenName
][
$tokenKey
];
}
else
{
$tokenValue
=
$tokenType
(microtime(TRUE));
$_SESSION
[
$tokenName
][
$tokenKey
] =
$tokenValue
;
}
$token
=
'<input type="hidden" name="'
.
$tokenName
.
'" value="'
.
$tokenKey
.
'_'
.
$tokenValue
.
'" />'
;
return
$token
;
}
|
此段代码主要是在TP开启表单验证的情况下,以TOKEN_NAME和当前URI的md5为健生成令牌值,再在用户提交表单时,先验证下是否存在该session,没有则返回false,有则紧接着和表单字段TOKEN_NAME验证下,如果一致先删除此session(作用时避免下次提交出先表单令牌错误),返回ture,否则返回false.
ok,回到主题,TP下表单提交之所以会出现令牌错误,那么就只有两种可能 。
1. 在令牌开启的状态下,提交的表单中,没有TOKEN_NAME字段或是没有相应session(当前提交表单环境下,没有生成相应session,这个主要是在用户提交后报错用户紧接着又刷新当前页面,同时编辑页面和展示页面是在同一个方法里) 。
2. 有session变量,但前后值不一样 。
我们项目之所以出现此错误,可以看看下面配置 。
1
2
3
4
5
6
7
|
return
array
(
'TOKEN_ON'
=>
'false'
,
'TOKEN_NAME'
=>
'__hash__'
,
'TOKEN_TYPE'
=>
'md5'
,
'TOKEN_RESET'
=>
'true'
,
'DB_FIELDTYPE_CHECK'
=>
'true'
);
|
本来应该写成布尔值的false,不知道哪位大侠任性的写成字符串的false了,那么判断时当然会按开启表单令牌的逻辑来,而且项目中,添加、编辑和展示都是同一个方法,一旦验证出错,一般程序处理逻辑会返回原有的界面,那么就和上次是同一个表单了,连续提交同一个表单也就相当于重复提交,那么便会报“表单令牌错误”.
希望本文所述对大家基于ThinkPHP框架的PHP程序设计有所帮助.
最后此篇关于ThinkPHP下表单令牌错误与解决方法分析的文章就讲到这里了,如果你想了解更多关于ThinkPHP下表单令牌错误与解决方法分析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
thinkphp开发图片上传,图片异步上传是目前比较方便的功能,这里我就不写css文件了,将代码写出来。引入核心文件下载https://github.com/carlcarl/A... HTML
现在谁不开发接口的呢?但是在接口开发过程中,报错误html">异常后居然返回错误的信息依然是html信息!TP官方也不知道为啥不添加,说好的为接口而生,我的解决方案也很简单,把系统的
thinkphp 抓取网站的内容并且保存到本地的实例详解 我需要写这么一个例子,到电子课本网下载一本电子书。 电子课本网的电子书,是把书的每一页当成一个图片,然后一本书就是有很多张图片,我需要批
假设数据库中会计科目数据表的字段为:id,code,name,islast。分别为自增主键,科目编码,科目名称,是否为末级("1"表示末级科目)。 这里在Thinkphp的模型
本文实例讲述了thinkphp+phpexcel实现excel报表输出功能。分享给大家供大家参考,具体如下: 准备工作: 1.下载phpexcel1.7.6类包; 2.解压至tp框架的thin
ThinkPHP 内置的模板引擎来定义模板文件,以及使用加载文件、模板布局和模板继承等高级功能。 每个模板文件在执行过程中都会生成一个编译后的缓存文件,其实就是一个可以运行的 PHP 文件。 引
本文实例讲述了thinkPHP+ajax实现统计页面pv浏览量的方法。分享给大家供大家参考,具体如下: 统计pv量很常用,下面的代码用ajax实现的,使用ajax可以避免页面缓存造成的影响,只要客
在很多网站中都会有使用404页面的时候,在ThinkPHP框架中该如何设置呢,接下来我介绍其中一种方法 1、首先要在Lib/Action 下建立EmptyAction.class.php模块 内容
话不多说,请看代码: ? 1
ThinkPHP 模板substr的截取字符串函数 在Common/function.php加上以下代码 ?
先上效果图: 那个file按钮样式先忽略 点击选择图片(浏览),随便选一张图片 js代码如下 ?
本文实例分析了thinkPHP js文件中U方法不被解析问题。分享给大家供大家参考,具体如下: 我想在js文件中写ajax, 写完发现异常, 本以为是js文件中不支持ajax 后来发现时地址
使用TP 3.2框架 ? 1
本文实例讲述了thinkphp,onethink和thinkox中验证码不显示的解决方法。分享给大家供大家参考,具体如下: 使用验证码的时候,一开始正常,后来不显示了 网上说是utf-8的编码问
1、基础知识 1.手机APP的类型 移动端的应用有这几种:WebApp,NativeApp,HybridApp。 WebApp 就是手机网站,需要用手机浏览器访问。 NativeApp是用
ThinkPHP CURD操作的查询方法中最常用但也是最复杂的就是where方法。where方法也属于模型类的连贯操作方法之一,主要用于查询和操作条件的设置。 where方法的用法是ThinkPH
ThinkPHP CURD方法的limit方法也是模型类的连贯操作方法之一,主要用于指定查询和操作的数量,特别在分页查询的时候使用较多。并且ThinkPHP的limit方法可以兼容所有的数据库驱动类
ThinkPHP CURD方法的page方法也是模型连贯操作方法之一,是完全为分页查询而诞生的一个人性化操作方法。 用法 我们在前面已经分析了关于limit方法用于分页查询的情况,而page方法则
ThinkPHP CURD方法的table方法也属于模型类的连贯操作方法之一,该方法主要用于指定操作的数据表。 具体用法如下: 一般情况下,操作模型的时候系统能够自动识别当前对应的数据表,所以,
ThinkPHP CURD方法的order方法属于模型的连贯操作方法之一,该方法用于对操作的结果排序。 具体用法如下: ?
我是一名优秀的程序员,十分优秀!