F66永乐集团首页官网F66永乐集团首页官网


F66永乐集团APP

防止活动上线时 微信openid 被伪造的解决办法

背景

前不久上线了一个 campaign 项目,一个 h5,后端为php,用户可以在微信中通过网页授权的方式登录,然后用微信 openid 作为唯一标识符进行签到和抽奖的操作。

结果后期出现了很多脏数据来冒领抽奖的操作,这些脏数据的出现是因为 openid 被伪造从而顺利入库。

方法

解决问题的思路就是不让 openid 伪造,有两种办法:

方法一、每次获取 openid 参数时,调用微信公众平台的“获取用户基本信息”的接口

方法二、采用 openid 加密的方法

结论:方法一这个接口官方有调用频率的限制,所以我们采用方法二

改造后的业务流程图

这里需要改造两块代码:

1、微信授权接口2、campagin api接口

采用对称加密

如上图所示:

1、加密的对策是:微信授权的时候,后端把回调给前端的 openid 进行加密;调用 api 的时候,前端再把授权得到的加密后的 openid 传给后端,后端先做解密操作,然后再进行剩下的业务逻辑,如果解密操作失败,则认定openid非法,拒绝此次请求2、因为 campaign 服务器同时负责加密和解密,可采用对称加密算法,这里我们选用更先进的 AES 加密算法

加密工具函数的代码如下:

function encrypt($string, $operation, $key = ""){ $key = md5($key); $key_length = strlen($key); $string = $operation == "D" ? base64_decode($string) : substr(md5($string . $key), 0, 8) . $string; $string_length = strlen($string); $rndkey = $box = array(); $result = ""; for ($i = 0; $i <= 255; $i++) { $rndkey[$i] = ord($key[$i % $key_length]); $box[$i] = $i; } for ($j = $i = 0; $i < 256; $i++) { $j = ($j + $box[$i] + $rndkey[$i]) % 256; $tmp = $box[$i]; $box[$i] = $box[$j]; $box[$j] = $tmp; } for ($a = $j = $i = 0; $i < $string_length; $i++) { $a = ($a + 1) % 256; $j = ($j + $box[$a]) % 256; $tmp = $box[$a]; $box[$a] = $box[$j]; $box[$j] = $tmp; $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); } if ($operation == "D") { if (substr($result, 0, 8) == substr(md5(substr($result, 8) . $key), 0, 8)) { return substr($result, 8); } else { return ""; } } else { return str_replace("=", "", base64_encode($result)); }}function encrypt_string($str){ $key = "test"; //这里的$key是密钥,请自行定义 return encrypt($str, "E", $key); //加密}function decode_string($str){ $key = "test"; //这里的$key是密钥,请自行定义 return encrypt($str, "D", $key); //解密}

调用:

$openid_param = encrypt_string($openid_param);$openid_param = decode_string($openid_param);//如果$openid_param === false,则openid非法!

欢迎阅读本文章: 谭付国

F66永乐国际官方网站

F66永乐集团APP