/** * 检查参数签名 */ function authSig($request) { $method = $request['m']; $param = $request['p']; if ($param['signature']) { $signature = $param['signature']; unset($param['signature']); $keys = array_keys($param); sort($keys); $s = ''; foreach ($keys as $key) { $value = $param[$key]; if (is_string($value) || is_numeric($value) || is_bool($value)) { $s .= '&' . $key . '=' . $value; } } $s = substr($s, 1) . $method . P_VERSION . '~@#1xdaf,dmuopamie%%123.'; $mysig = md5($s); if ($mysig != $signature) { glog::info("签名不对[{$mysig}]!=[{$signature}], " . json_encode($request), 'sign'); return array('s' => StatusCode::invalid_siginature, 'msg' => 'invalid signature'); } $timestamp = $param['timestamp']; if ($method == 'System.login') { // 手机设备时间和服务器时间可能有差异,所以第一次请求 System.login 时不验证时间。 return false; } // 1. 对 timestamp 做验证 与 服务器当前时间相差太多的 认为是不合法的请求 $now = getApp()->now; if (abs($now - $timestamp) > 300) { $ts1 = date('Y-m-d H:i:s', $now); $ts2 = date('Y-m-d H:i:s', $timestamp); glog::info("请求时间异常 server[{$ts1}], client[{$ts2}], " . json_encode($request), 'sign'); return false; return array('s' => StatusCode::invalid_request_time, 'msg' => 'invalid timestamp'); } // 2. 记录用户上次调用这个接口的时间戳,如果新的 timestamp <= old_timestamp 则认为是不合法的请求 $uid = getApp()->getuid(); $section_id = getApp()->getsec(); if ($uid && $section_id) { if (model_Util::inBlacklist($uid)) { //黑名单访问,禁止 glog::info("黑名单中玩家[{$uid}]访问分区[{$section_id}] " . json_encode($request), 'blacklist'); return array('s' => StatusCode::invalid_request_time, 'msg' => "uid[{$uid}] is in blacklist"); } try { $redis = DbConfig::getRedis('cache'); $timestamp_key = "sig_{$section_id}_{$uid}_{$method}"; $old_timestamp = $redis->get($timestamp_key); if (is_numeric($old_timestamp)) { // 手机端网络超时后重试,后台可能会收到两次同样时间戳的请求 所以 $timestamp == $old_timestamp 还是很有可能的 if ($timestamp < $old_timestamp) { $ts1 = date('Y-m-d H:i:s', $old_timestamp); $ts2 = date('Y-m-d H:i:s', $timestamp); glog::info("请求时间异常, 上次请求[{$ts1}], 本次请求[{$ts2}], " . json_encode($request), 'sign'); return false; return array('s' => StatusCode::outdated_siginature, 'msg' => 'outdated signature', 'debug' => "old_timestamp: {$old_timestamp}"); } else { $redis->multi(); $redis->set($timestamp_key, $timestamp); $redis->expire($timestamp_key, 360); $redis->exec(); return false; } } else { $redis->multi(); $redis->set($timestamp_key, $timestamp); $redis->expire($timestamp_key, 360); $redis->exec(); return false; } } catch (Exception $ex) { error_log("无法连接 cache redis "); return false; } } return false; } glog::info("没有签名," . json_encode($request), 'sign'); return array('s' => StatusCode::invalid_siginature, 'msg' => 'no signature'); }
/** * 官网支付 */ private function processWanpay(&$data) { $data['source'] = "internal"; if ($data['product_id'] == 'custom' && $data['cash'] < 1000) { //自定义小于1000最低限额 //glog::info("异常的支付数据,自定义金额小于1000[uid:$uid][section_id:$sec][transaction_id:$transaction_id][product_id:$product_id]", 'payment'); //echo json_encode(array('s'=>StatusCode::exception,'msg'=>'error2')); //die; } if (intval($data['cash']) < 6) { glog::info("异常的支付数据,转换到元小于6![uid:{$uid}][section_id:{$sec}][transaction_id:{$transaction_id}][product_id:{$product_id}]", 'payment'); echo json_encode(array('s' => StatusCode::exception, 'msg' => 'error3')); die; } }
/** * @author 符璨 * @desc * 从cdkey_task取出待处理的cdkey任务进行处理 * 批量生成cdkey */ public static function action_gen_cdkey() { $redis = DbConfig::getRedis('realtime_stat'); $process_id = getmypid(); //从cdkey中取出一条状态为0(未处理cdkey生成记录),并更新为1(正在处理) $mc = new PL_Db_Mongo(DbConfig::getMongodb('userlogin')); $mc->switchColl('cdkey_task'); $cdkey_task = $mc->findOne(array('status' => 0)); //没有待处理的任务 if ($cdkey_task == NULL) { return; } glog::info("[{$process_id}] gen cdkey worker started", 'cdkey'); $task_id = $cdkey_task['_id']; $mc->update(array('_id' => $task_id), array('$set' => array('status' => 1))); $pa = $cdkey_task; unset($pa['status']); $num = $pa['num']; $task_id = $cdkey_task['_id']; //根据cdkey_task的内容生成cdkey $mc->switchColl('cdkey'); while ($num--) { $pa['_id'] = model_Cdkey::genCdkey(13); $pa['task_id'] = $task_id->__toString(); //try以防有重复的cdkey try { $cdkey = $mc->insert($pa); //redis中统计当前已生成的cdkey数目 $redis->hIncrBy('cdkey_task', $task_id, 1); $redis->lpush("cdkey_{$task_id}", $pa['_id']); } catch (Exception $ex) { $exception_cnt--; $num++; glog::info("[{$process_id}] gen cdkey worker:Duplicated _id {$pa['_id']}", 'cdkey'); if (!$exception_cnt) { break; } continue; } $exception_cnt = 10; } $mc->switchColl('cdkey_task'); $mc->update(array('_id' => $task_id), array('$set' => array('status' => 2))); $redis->hDel('cdkey_task', $task_id); glog::info("[{$process_id}] gen cdkey worker completed", 'cdkey'); }