BaseController.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2017~2021 https://www.yiovo.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
  8. // +----------------------------------------------------------------------
  9. // | Author: 萤火科技 <admin@yiovo.com>
  10. // +----------------------------------------------------------------------
  11. declare (strict_types=1);
  12. namespace cores;
  13. use Exception;
  14. use think\App;
  15. use think\Validate;
  16. use cores\authorize\Http;
  17. use cores\authorize\Tools;
  18. use cores\authorize\AuthFile;
  19. use app\common\exception\BaseException;
  20. use think\exception\ValidateException;
  21. /**
  22. * 控制器基础类
  23. */
  24. abstract class BaseController
  25. {
  26. /**
  27. * Request实例
  28. * @var \think\Request
  29. */
  30. protected $request;
  31. /**
  32. * 应用实例
  33. * @var \think\App
  34. */
  35. protected $app;
  36. /**
  37. * 是否批量验证
  38. * @var bool
  39. */
  40. protected $batchValidate = false;
  41. /**
  42. * 控制器中间件
  43. * @var array
  44. */
  45. protected $middleware = [];
  46. // 当前是否初始化了 [如果为false 那么基类里的方法不允许被调用]
  47. private $isInitialized = false;
  48. /**
  49. * 构造方法
  50. * BaseController constructor.
  51. * @param App $app
  52. * @throws BaseException
  53. */
  54. public function __construct(App $app)
  55. {
  56. $this->app = $app;
  57. $this->request = $this->app->request;
  58. // 控制器初始化
  59. $this->initialize();
  60. // 授权验证
  61. $this->authorize();
  62. }
  63. // 初始化
  64. protected function initialize()
  65. {
  66. }
  67. /**
  68. * 系统授权验证
  69. * @throws BaseException
  70. */
  71. private final function authorize()
  72. {
  73. // 验证auth文件是否合法[3.1%概率]
  74. Tools::probability(3.1) && $this->___();
  75. // 验证授权域名是否合法[0.4%概率]
  76. Tools::probability(0.4) && $this->____();
  77. // 标记为已初始化
  78. $this->isInitialized = true;
  79. }
  80. /**
  81. * 验证auth文件是否合法
  82. * @return bool
  83. * @throws BaseException
  84. */
  85. private final function ___()
  86. {
  87. $this->o00oo000o();
  88. return true;
  89. }
  90. /**
  91. * 验证授权域名是否合法
  92. * @return mixed|bool
  93. * @throws BaseException
  94. */
  95. private final function ____()
  96. {
  97. // 获取当前域名
  98. $host = $this->o0ooo00oo();
  99. // 实例化一个http类
  100. $Http = $this->o0ooo000o();
  101. // 请求api:根据域名查询是否已授权
  102. $result = $Http->domain($host);
  103. $result === false && throwError('很抱歉,检测到域名授权异常,系统将无法正常运行');
  104. return $result;
  105. }
  106. /**
  107. * 实例化一个http类
  108. * @return Http
  109. * @throws BaseException
  110. */
  111. private final function o0ooo000o()
  112. {
  113. // 获取auth文件中的注册码数据[解密后的]
  114. $authData = $this->o00oo000o();
  115. // 实例化一个http类
  116. $Http = new Http();
  117. $Http->setAppToken($authData['AppID'], $authData['AppSecret']);
  118. return $Http;
  119. }
  120. /**
  121. * 获取auth文件中的注册码数据[解密后的]
  122. * @return array
  123. * @throws BaseException
  124. */
  125. private final function o00oo000o()
  126. {
  127. // 获取auth文件中的注册码数据[解密后的]
  128. $AuthFile = AuthFile::getInstance();
  129. $auth = $AuthFile->getAuthFile();
  130. $authData = $AuthFile->getActivationData($auth);
  131. $this->oo0000oo($auth, $authData);
  132. return $authData;
  133. }
  134. /**
  135. * 比较授权文件合法性(明文和密文是否吻合)
  136. * @param array $auth
  137. * @param array $authData
  138. * @return bool
  139. * @throws BaseException
  140. * @throws \Exception
  141. */
  142. private final function oo0000oo(array $auth, array $authData)
  143. {
  144. // 验证授权文件签名
  145. $temp = Tools::pick($auth, ['name', 'contact', 'UserKey', 'AppID', 'expirationTime', 'ActivationCode', 'CoreData']);
  146. $sign = Tools::myhash(Tools::jsonEncode($temp) . "_{$temp['UserKey']}", 32);
  147. if ($sign !== $auth['sign']) {
  148. throwError('很抱歉,检测到授权文件异常,系统将无法正常运行,请检查后端根目录auth文件是否被篡改');
  149. }
  150. // 验证授权文件到期时间
  151. $date = new \DateTime($authData['expirationTime']);
  152. if (date('Ymd') > $date->format('Ymd')) {
  153. throwError('很抱歉,检测到授权文件授权时间已过期,系统将无法正常运行');
  154. }
  155. return true;
  156. }
  157. /**
  158. * 获取当前域名
  159. * @return string
  160. */
  161. private final function o0ooo00oo()
  162. {
  163. $host = strval($_SERVER['HTTP_X_FORWARDED_HOST'] ?? getenv()['HTTP_HOST']);
  164. if (request()->host() !== $host) {
  165. return '';
  166. }
  167. return request()->host();
  168. }
  169. /**
  170. * 验证当前是否已经初始化过
  171. * @throws Exception
  172. */
  173. private final function checkInitialized()
  174. {
  175. if (!$this->isInitialized) {
  176. throw new Exception('Currently not initialized');
  177. }
  178. }
  179. /**
  180. * 验证数据
  181. * @access protected
  182. * @param array $data 数据
  183. * @param string|array $validate 验证器名或者验证规则数组
  184. * @param array $message 提示信息
  185. * @param bool $batch 是否批量验证
  186. * @return array|string|true
  187. * @throws ValidateException
  188. */
  189. protected function validate(array $data, $validate, array $message = [], bool $batch = false)
  190. {
  191. if (is_array($validate)) {
  192. $v = new Validate();
  193. $v->rule($validate);
  194. } else {
  195. if (strpos($validate, '.')) {
  196. // 支持场景
  197. [$validate, $scene] = explode('.', $validate);
  198. }
  199. $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
  200. $v = new $class();
  201. if (!empty($scene)) {
  202. $v->scene($scene);
  203. }
  204. }
  205. $v->message($message);
  206. // 是否批量验证
  207. if ($batch || $this->batchValidate) {
  208. $v->batch(true);
  209. }
  210. return $v->failException(true)->check($data);
  211. }
  212. /**
  213. * 返回封装后的 API 数据到客户端
  214. * @param int|null $status
  215. * @param string $message
  216. * @param array $data
  217. * @return \think\response\Json|array
  218. */
  219. protected final function renderJson(int $status = null, string $message = '', array $data = [])
  220. {
  221. $this->checkInitialized();
  222. return json(compact('status', 'message', 'data'));
  223. }
  224. /**
  225. * 返回操作成功json
  226. * @param array|string $data
  227. * @param string $message
  228. * @return array
  229. */
  230. protected final function renderSuccess($data = [], string $message = 'success')
  231. {
  232. if (is_string($data)) {
  233. $message = $data;
  234. $data = [];
  235. }
  236. return $this->renderJson(config('status.success'), $message, $data);
  237. }
  238. /**
  239. * 返回操作失败json
  240. * @param string $message
  241. * @param array $data
  242. * @return array
  243. */
  244. protected final function renderError(string $message = 'error', array $data = [])
  245. {
  246. return $this->renderJson(config('status.error'), $message, $data);
  247. }
  248. /**
  249. * 获取post数据 (数组)
  250. * @param $key
  251. * @return mixed
  252. */
  253. protected final function postData($key = null)
  254. {
  255. $this->checkInitialized();
  256. return $this->request->post(empty($key) ? '' : "{$key}/a");
  257. }
  258. /**
  259. * 获取post数据 (数组)
  260. * @param $key
  261. * @return mixed
  262. */
  263. protected final function postForm($key = 'form')
  264. {
  265. return $this->postData($key);
  266. }
  267. }