1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- <?php
- namespace app\utils;
- use think\Request;
- /**
- * 校验sign 校验签名,防止刷重要接口
- */
- class CheckSignUtil{
- /**
- * 校验接口名单
- */
- const hitList = [
- 'api/gift/givegift_typing',// 聊天赠送礼物
- 'api/usercenter/chat_once',// 文字聊天扣费
- 'api/usercenter/voice_onemin',// 语音聊天扣费
- 'api/usercenter/videochat_onemin',// 视频聊天扣费
- ];
- /**
- * 失效时间 单位 seconds
- */
- const deadTime = 150;
- /**
- * 校验签名
- * @param $path
- * @param $token
- * @param $sign
- * @return array
- */
- public static function check($path,$token,$sign): array
- {
- if (!in_array($path,self::hitList)){
- return [true,'success'];
- }
- if (empty($sign)){
- return [false,'签名缺失!'];
- }
- // 签名解密
- $rsa = new RsaUtil();
- $sign = $rsa->privateDecrypt($sign);
- if (!$sign || !$sign = json_decode($sign,true)){
- return [false,'签名错误!'];
- }
- if (empty($sign['token']) || empty($sign['timestamp']) || empty($sign['timezone'])){
- return [false,'签名参数错误!'];
- }
- if ($token != $sign['token']){
- return [false,'签名参数校验错误!'];
- }
- if ($token != $sign['token']){
- return [false,'签名参数校验错误!'];
- }
- // 根据客户端 时区 校验时间戳
- $now = new \DateTime(null, new \DateTimeZone((string)$sign['timezone']));
- $time = (int)($now->format('U'));
- // 如果 前端请求时间戳异常,则认为 请求被篡改 或 请求超时
- if ($sign['timestamp'] <= ($time - self::deadTime)){
- return [false,'签名过期,请求已过期!'];
- }
- // 请求唯一key
- $key = md5($sign['token'] . '_' .((string)$sign['timestamp']));
- // redis 重复请求
- if (!RedisUtil::getInstance('check_sign_lock',$key)->tryTimes(self::deadTime,1)) {
- return [false,'点的太快啦!'];
- }
- return [true,'success'];
- }
- }
|