PHP-ThinkPHP中的表单令牌是什么原理

 我来答
Vw安全联盟
2018-07-31 · 超过11用户采纳过TA的回答
知道答主
回答量:20
采纳率:100%
帮助的人:1.8万
展开全部
你说的是token吧
有效防止重复提交,以及跨站伪造请求
Token,就是令牌,最大的特点就是随机性,不可预测。一般黑客或软件无法猜测出来。
Token一般用在两个地方——防止表单重复提交、anti csrf攻击(跨站点请求伪造)。
原理上都是通过session token来实现的。当客户端请求页面时,服务器会生成一个随机数Token,并且将Token放置到session当中,然后将Token发给客户端(一般通过构造hidden表单)。下次客户端提交请求时,Token会随着表单一起提交到服务器端。
然后,如果应用于“anti csrf攻击”,则服务器端会对Token值进行验证,判断是否和session中的Token值相等,若相等,则可以证明请求有效,不是伪造的。
纯手打,望采纳
百度网友ad45923b8
2018-09-30 · 知道合伙人软件行家
百度网友ad45923b8
知道合伙人软件行家
采纳数:262 获赞数:386
从事IT互联网行业16年,经验丰富,擅长ASP、HTML、Javascript,Css,JQuery,PHP,PS,FL,AI,E,服务器等

向TA提问 私信TA
展开全部

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。

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
杰克的豌豆
2018-08-10 · TA获得超过160个赞
知道答主
回答量:132
采纳率:66%
帮助的人:17.8万
展开全部

这是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;
    }
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
九月枫燃
2018-09-15 · TA获得超过109个赞
知道答主
回答量:220
采纳率:45%
帮助的人:29.7万
展开全部
生成一个token值,用session缓存起来,这个过程是在打开填写表单的页面时就生成了,然后我们填写完数据是提交到php页面,此时的token值会和之前缓存起来的值进行对比,如果不一样就会报错。
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
帐号已注销
推荐于2016-07-26 · 超过116用户采纳过TA的回答
知道小有建树答主
回答量:190
采纳率:0%
帮助的人:223万
展开全部
它是用来防止表单非法提交,令牌就是为每个表单生成的唯一ID用来验证安全性、是不是合法的表单提交。
本回答被提问者和网友采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 更多回答(5)
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式