概述
在红包活动中,防止恶意刷红包是保障活动公平性的重要环节。本文介绍一种基于签名验证的PHP防刷方案,通过动态生成的签名参数来防止恶意请求。
核心原理
由于PHP代码在服务器端执行,客户端无法查看签名生成算法。利用这一特性,可以通过时间戳和自定义密钥生成签名,确保每次请求的唯一性和合法性。
实现代码
1. 前端生成签名参数
$signarray = array();
$signarray['name'] = 'wefwf';
$time = time();
$signarray['time'] = $time;
$signarray['phone'] = 'wef';
$signcreate = $this->str_encrypt($signarray);
$this->assign('time', $time);
$this->assign('signcreate', $signcreate);
$this->display();
2. 测试接口
public function signverifytest(){
$issign = $this->verify($_POST);
if(!$issign){
echo json_encode(array('success'=>0,'msg'=>'签名验证失败','data'=>''));
exit();
}else{
echo json_encode(array('success'=>0,'msg'=>'签名验证成功','data'=>''));
exit();
}
}
3. 签名验证方法
public function verify($parameters)
{
//如果sign不一致 签名失败
if ($parameters['sign'] != $this->str_encrypt($parameters)) {
return 0;
} else {
return 1;
}
}
4. 加密算法
public function str_encrypt($parameters)
{
unset($parameters['sign']);
$parameters['key'] = 'mykey';
ksort($parameters);
$signPars = $this->url_build($parameters);
$signPars = trim($signPars,'&');
return strtolower(md5($signPars));
}
5. 参数拼接方法
public function url_build($parameters)
{
$signPars = '';
foreach ($parameters as $k => $v) {
if (isset($v)) {
$signPars .= $k . '=' . $v . '&';
}
}
return $signPars;
}
防刷要点
- 时间戳校验:每次请求携带时间戳,服务器可校验时间差值,防止重放攻击
- 密钥保护:加密密钥存储在服务器端,客户端无法获取完整的签名算法
- 签名一致性:客户端提交签名,服务器重新计算并比对,确保数据未被篡改
- 参数排序:使用ksort对参数排序后再加密,保证签名计算的一致性
增强方案
除了签名验证外,还可以结合以下手段增强防刷效果:
- IP频率限制:限制同一IP在单位时间内的请求次数
- Redis缓存:使用Redis记录请求频次,实现分布式限流
- 验证码:在关键操作前增加图形验证码或滑动验证
- 用户鉴权:要求用户登录后进行操作,结合openid等唯一标识
- Token机制:使用一次性Token防止重复提交
总结
本方案的核心优势在于:由于客户端无法看到PHP代码,所以自然看不到time和sign的完整生成算法,从而有效防止了刷红包行为。结合IP限制、频率限制、Redis防并发等手段,可以构建更完善的防刷体系,保障红包活动的公平性。
ps: 主要是利用看不到PHP代码,所以自然看不到time和sign的生成算法,所以就防止了刷红包。

发表评论 取消回复