You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
think-library/src/ApiController.php

257 lines
6.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
// +----------------------------------------------------------------------
// | ThinkLibrary 6.0 for ThinkPhP 6.0
// +----------------------------------------------------------------------
// | 版权所有 2017~2020 [ https://www.dtapp.net ]
// +----------------------------------------------------------------------
// | 官方网站: https://gitee.com/liguangchun/ThinkLibrary
// +----------------------------------------------------------------------
// | 开源协议 ( https://mit-license.org )
// +----------------------------------------------------------------------
// | gitee 仓库地址 https://gitee.com/liguangchun/ThinkLibrary
// | github 仓库地址 https://github.com/GC0202/ThinkLibrary
// | Packagist 地址 https://packagist.org/packages/liguangchun/think-library
// +----------------------------------------------------------------------
namespace DtApp\ThinkLibrary;
use DtApp\ThinkLibrary\helper\ValidateHelper;
use stdClass;
use think\App;
use think\exception\HttpResponseException;
use think\Request;
/**
* 标准Api控制器基类
* Class ApiController
* @package DtApp\ThinkLibrary
*/
abstract class ApiController extends stdClass
{
/**
* 应用容器
* @var App
*/
public $app;
/**
* 请求对象
* @var Request
*/
public $request;
/**
* 解密后数据
* @var
*/
private $aes_decrypt_data;
/**
* 加密相关的东西
* @var string
*/
private $aes_md5, $aes_md5_iv = '';
/**
* ApiController constructor.
* @param App $app
*/
public function __construct(App $app)
{
$this->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 = []): void
{
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): void
{
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): void
{
throw new HttpResponseException(redirect($url, $code));
}
/**
* @param array $rules
* @param string $type
* @return mixed
*/
protected function _vali(array $rules, $type = '')
{
return ValidateHelper::instance()
->init($rules, $type);
}
/**
* 获取解密后的数据
* @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);
}
}