必须使用服务端生成的一次性安全令牌防止csrf攻击:一、基于session方案用random_bytes生成并校验token,超时1800秒即失效;二、无session方案将加密的token元数据存文件或数据库,支持分布式环境。

如果您的PHP应用程序需要防止跨站请求伪造(CSRF)攻击,必须确保每个表单提交都携带服务端生成且一次性有效的安全令牌。以下是实现Token验证的多种函数级方案:
一、基于Session的Token生成与校验函数
该方法利用PHP Session存储Token值,在表单渲染时嵌入隐藏字段,并在接收请求时比对Session中存储的Token与提交值是否一致且未被重复使用。
1、定义生成Token的函数,使用random_bytes生成加密安全随机字符串并进行base64编码和去杂字符处理;
2、将生成的Token存入$_SESSION['csrf_token'],同时设置$_SESSION['csrf_token_time']记录生成时间;
3、定义校验函数,检查$_POST中是否存在'csrf_token'字段,确认其值等于$_SESSION['csrf_token'],且当前时间与$_SESSION['csrf_token_time']之差不超过1800秒;
4、校验通过后立即调用unset($_SESSION['csrf_token'])和unset($_SESSION['csrf_token_time'])使Token失效。
二、基于独立Token存储的无Session方案
该方法不依赖Session机制,将Token元数据(如过期时间、使用状态)加密后写入本地文件或数据库,并通过唯一ID关联表单,适用于分布式或无状态环境。
1、定义generate_standalone_token()函数,生成32字节随机值作为Token ID,再生成64字节密钥派生Token内容;
2、使用openssl_encrypt将序列化的['expires'=>time()+1800, 'used'=>false]数组加密,以Token ID为键存入/tmp/csrf_tokens/目录下的文件;
3、在表单中输出php echo $token_id; ?>">;
4、接收请求后,读取对应Token ID的加密文件,解密后验证expires字段未过期且used为false,验证成功后将used设为true并重写文件。
三、结合HMAC签名的防篡改Token方案
该方法不存储Token状态,而是将时间戳、随机盐值与密钥通过HMAC-SHA256签名组合成自包含Token,服务端仅需重算签名即可完成校验,降低存储依赖。
1、定义create_hmac_token()函数,生成microtime(true)的时间戳和uniqid('', true)的随机盐;
2、拼接字符串:$data = $timestamp . '|' . $salt;
3、计算签名:$signature = hash_hmac('sha256', $data, $_ENV['CSRF_SECRET_KEY']);
4、将$data和$signature用冒号连接并base64_encode,生成最终Token字符串;
5、校验时先base64_decode,分割出$data和$signature,重新计算HMAC并与提交值比对,同时检查$time = (float)explode('|', $data)[0]是否在当前时间±1800秒范围内。
四、Laravel风格的一次性Token中间件函数封装
该方法模拟现代框架的中间件逻辑,将Token生成、注入与校验抽象为可复用函数,支持按路由路径绑定Token生命周期,避免全局污染。
1、定义csrf_token_for_route($route_path)函数,将$route_path与当前时间哈希后作为键生成Token,并存入$_SESSION["csrf_{$route_path}"];
2、定义csrf_field($route_path)函数,输出隐藏输入框,name为"__token_{$route_path}",value为csrf_token_for_route($route_path)返回值;
3、定义validate_csrf_for_route($route_path)函数,从$_POST中提取"__token_{$route_path}",比对$_SESSION["csrf_{$route_path}"];
4、校验成功后调用unset($_SESSION["csrf_{$route_path}"]),确保同一路径的Token仅能使用一次。
五、防御重放的双因子Token函数组合
该方法引入客户端指纹(User-Agent + Remote IP哈希)作为第二因子,使Token与发起请求的设备强绑定,防止Token被截获后在其他设备重放。
1、定义generate_bound_token()函数,组合$_SERVER['HTTP_USER_AGENT']、$_SERVER['REMOTE_ADDR']、microtime(true)和random_bytes(16);
2、对组合字符串执行hash_pbkdf2('sha256', $input, $_ENV['CSRF_SALT'], 10000, 32)生成Token;
3、将Token存入$_SESSION['bound_csrf_token']并设置有效期;
4、校验时重新采集相同字段,执行完全相同的PBKDF2运算,比对结果是否与$_POST['csrf_token']一致;
5、若不一致,直接拒绝请求且不提供任何差异提示,防止指纹探测。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











