PHP-ThinkPHP中的表单令牌是啥原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PHP-ThinkPHP中的表单令牌是啥原理相关的知识,希望对你有一定的参考价值。
你说的是token吧有效防止重复提交,以及跨站伪造请求
Token,就是令牌,最大的特点就是随机性,不可预测。一般黑客或软件无法猜测出来。
Token一般用在两个地方——防止表单重复提交、anti csrf攻击(跨站点请求伪造)。
原理上都是通过session token来实现的。当客户端请求页面时,服务器会生成一个随机数Token,并且将Token放置到session当中,然后将Token发给客户端(一般通过构造hidden表单)。下次客户端提交请求时,Token会随着表单一起提交到服务器端。
然后,如果应用于“anti csrf攻击”,则服务器端会对Token值进行验证,判断是否和session中的Token值相等,若相等,则可以证明请求有效,不是伪造的。
纯手打,望采纳 参考技术A
thinlphp框架项目中开启表单令牌,要在配置文件中做如下配置
array(// 是否开启令牌验证
'TOKEN_ON' => true,
// 令牌验证的表单隐藏字段名称
'TOKEN_NAME' => '__hash__',
//令牌哈希验证规则 默认为MD5
'TOKEN_TYPE' => 'md5',
//令牌验证出错后是否重置令牌 默认为true
'TOKEN_RESET' => true
);
编辑数据
$table = D('table');if (!$table->create())
exit($this->error($table->getError()));
TP框架中Model.class.php中的create方法
/*** 创建数据对象
* @access public
* @param mixed $data 创建数据
* @param string $type 状态
* @return mixed
*/
function create($data = '', $type = '')
// 表单令牌验证
if (!$this->autoCheckToken($data))
$this->error = L('_TOKEN_ERROR_');
return false;
当autoCheckToken方法检测失败时会报错
// 自动表单令牌验证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文件
// 创建表单令牌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。
参考技术B这是thinkphp5的表单令牌生成源码,可以看到是加密了时间戳。
public function token($name = '__token__', $type = 'md5')$type = is_callable($type) ? $type : 'md5';
$token = call_user_func($type, $_SERVER['REQUEST_TIME_FLOAT']);
if ($this->isAjax())
header($name . ': ' . $token);
Session::set($name, $token);
return $token;
参考技术C 生成一个token值,用session缓存起来,这个过程是在打开填写表单的页面时就生成了,然后我们填写完数据是提交到php页面,此时的token值会和之前缓存起来的值进行对比,如果不一样就会报错。 参考技术D 它是用来防止表单非法提交,令牌就是为每个表单生成的唯一ID用来验证安全性、是不是合法的表单提交。本回答被提问者和网友采纳
以上是关于PHP-ThinkPHP中的表单令牌是啥原理的主要内容,如果未能解决你的问题,请参考以下文章
OAuth 2 中的不记名令牌和 token_type 是啥?