app = $app; $this->request = $app->request; $this->app->bind('DtApp\ThinkLibrary\ApiController', $this); if (in_array($this->request->action(), get_class_methods(__CLASS__))) { $this->error('Access without permission.'); } $this->initialize(); } /** * 控制器初始化 */ protected function initialize() { } /** * 返回失败的操作 * @param mixed $msg 消息内容 * @param mixed $data 返回数据 * @param integer $code 返回代码 */ public function error($msg = 'error', $code = 1, $data = []) { throw new HttpResponseException(json([ 'code' => $code, 'msg' => $msg, 'timestamp' => time(), 'data' => $data, ])); } /** * 返回成功的操作 * @param mixed $msg 消息内容 * @param mixed $data 返回数据 * @param integer $code 返回代码 */ public function success($data = [], $msg = 'success', $code = 0) { throw new HttpResponseException(json([ 'code' => $code, 'msg' => $msg, 'timestamp' => time(), 'data' => $data, ])); } /** * key * @param string $name 参数名 * @return $this */ public function setAesMd5($name = 'sniff_h5'): self { $value = config("dtapp.md5.{$name}"); $this->aes_md5 = $value; return $this; } /** * iv * @return $this */ private function setAesMd5Iv(): self { $value = config("dtapp.md5.bcw"); $this->aes_md5_iv = $value; return $this; } /** * 返回成功的操作 * @param mixed $data 返回数据 * @param mixed $msg 消息内容 * @param integer $code 返回代码 */ public function aesSuccess($data = [], $msg = 'success', $code = 0) { $timestamp = time(); throw new HttpResponseException(json([ 'code' => $code, 'msg' => $msg, 'timestamp' => $timestamp, 'data' => [ 'aes' => $this->encrypt($data, $timestamp) ], ])); } /** * URL重定向 * @param string $url 跳转链接 * @param integer $code 跳转代码 */ public function redirect($url, $code = 301) { throw new HttpResponseException(redirect($url, $code)); } /** * 数据回调处理机制 * @param string $name 回调方法名称 * @param mixed $one 回调引用参数1 * @param mixed $two 回调引用参数2 * @return boolean */ public function callback($name, &$one = [], &$two = []): bool { if (is_callable($name)) { return call_user_func($name, $this, $one, $two); } foreach ([$name, "_{$this->app->request->action()}{$name}"] as $method) { if (method_exists($this, $method) && false === $this->$method($one, $two)) { return false; } } return true; } /** * 获取解密后的数据 * @param string $name * @param null $default * @return mixed */ public function getAesDecryptData(string $name = '', $default = null) { if (empty($name)) { return $this->aes_decrypt_data; } return $this->aes_decrypt_data[$name] ?? $default; } /** * 验证接口签名 */ public function _judgeSign() { // 加密的数据参数 $aes = $this->request->post('aes', ''); if (empty($aes)) { $this->error('数据未签名!', 104); } // 获取时间数据 $timestamp = $this->request->get('timestamp', 0); // 判断是否有时间 if (empty($timestamp)) { $this->error('数据异常!', 105); } // 解密 $aes_decode = $this->decrypt($aes, $timestamp); if (empty($aes_decode)) { $this->error('解密失败', 106); } $data = json_decode($aes_decode, true); // 判断是不是小于服务器时间 $before = strtotime('-2minute'); $rear = strtotime('+2minute'); if ($timestamp <= $rear && $timestamp >= $before) { $this->aes_decrypt_data = $data; } else { $this->error('已超时,请重新尝试!'); } } /** * 加密 * @param $data * @param int $timestamp * @return bool|string */ private function encrypt($data, int $timestamp) { if (empty($this->aes_md5)) { $this->setAesMd5(); } if (empty($this->aes_md5_iv)) { $this->setAesMd5Iv(); } if (!empty(is_array($data))) { $data = json_encode($data); } return urlencode(base64_encode(openssl_encrypt($data, 'AES-128-CBC', $this->aes_md5, 1, $this->aes_md5_iv . $timestamp))); } /** * 解密 * @param string $data * @param int $timestamp * @return bool|false|string */ private function decrypt(string $data, int $timestamp) { if (empty($this->aes_md5)) { $this->setAesMd5(); } if (empty($this->aes_md5_iv)) { $this->setAesMd5Iv(); } return openssl_decrypt(base64_decode(urldecode($data)), "AES-128-CBC", $this->aes_md5, true, $this->aes_md5_iv . $timestamp); } }