OpenAuthRepository.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\common\repositories\openapi;
  12. use app\common\dao\openapi\OpenAuthDao;
  13. use app\common\repositories\BaseRepository;
  14. use crmeb\exceptions\AuthException;
  15. use FormBuilder\Factory\Elm;
  16. use think\exception\ValidateException;
  17. use think\facade\Cache;
  18. use think\facade\Config;
  19. use think\facade\Route;
  20. class OpenAuthRepository extends BaseRepository
  21. {
  22. const AUTH_TYPE_PRODUCT = '1';
  23. const AUTH_TYPE_ORDER = '2';
  24. public function __construct(OpenAuthDao $dao)
  25. {
  26. $this->dao = $dao;
  27. }
  28. /**
  29. * 创建
  30. * @param int $merId
  31. * @param array $data
  32. * @return \app\common\dao\BaseDao|\think\Model
  33. * @author Qinii
  34. * @day 2023/7/21
  35. */
  36. public function create(int $merId, array $data)
  37. {
  38. $data['access_key'] = $this->createAccessKey($merId);
  39. $data['secret_key'] = $this->createSecretKey($merId);
  40. $data['mer_id'] = $merId;
  41. return $this->dao->create($data);
  42. }
  43. /**
  44. * 列表
  45. * @param $where
  46. * @param $page
  47. * @param $limit
  48. * @return array
  49. * @author Qinii
  50. * @day 2023/7/21
  51. */
  52. public function getList($where,$page, $limit)
  53. {
  54. $where['is_del'] = 0;
  55. $query = $this->dao->getSearch($where)->hidden(['secret_key','delete_time'])->order('id ASC');
  56. $count = $query->count();
  57. $list = $query->page($page, $limit)->select();
  58. return compact('count','list');
  59. }
  60. /**
  61. * 添加编辑表单
  62. * @param int $merId
  63. * @param $id
  64. * @return \FormBuilder\Form
  65. * @author Qinii
  66. * @day 2023/7/21
  67. */
  68. public function form(int $merId, $id = 0)
  69. {
  70. $formData = [];
  71. if ($id) {
  72. $formData = $this->dao->getWhere(['id' => $id])->toArray();
  73. if (!$formData) throw new ValidateException('数据不存在');
  74. $form = Elm::createForm(Route::buildUrl('merchantOpenapiUpdate', ['id' => $id])->build());
  75. } else {
  76. $form = Elm::createForm(Route::buildUrl('merchantOpenapiCreate')->build());
  77. }
  78. $form->setRule([
  79. Elm::input('title', '标题:')->placeholder('请输入标题'),
  80. Elm::selectMultiple('auth', '权限:')->options([
  81. ['value' => self::AUTH_TYPE_PRODUCT,'label' => '商品'],
  82. ['value' => self::AUTH_TYPE_ORDER,'label' => '订单'],
  83. ]),
  84. Elm::input('mark', '备注')->placeholder('请输入备注'),
  85. Elm::switches('status', '是否开启:', 1)->activeValue(1)->inactiveValue(0)->inactiveText('关')->activeText('开'),
  86. Elm::number('sort', '排序:', 0)->precision(0)->max(99999),
  87. ]);
  88. return $form->setTitle($id ? '编辑授权账户' : '添加授权账户')->formData($formData);
  89. }
  90. /**
  91. * 生成 AccessKey
  92. * @param int $merId
  93. * @return string
  94. * @author Qinii
  95. * @day 2023/7/21
  96. */
  97. public function createAccessKey(int $merId)
  98. {
  99. list($msec, $sec) = explode(' ', microtime());
  100. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  101. $sn = $msectime . random_int(10000, max(intval($msec * 10000) + 10000, 98369));
  102. return 'M'.$merId.'os'.$sn;
  103. }
  104. /**
  105. * 生成 secret_key
  106. * @param int $merId
  107. * @return string
  108. * @author Qinii
  109. * @day 2023/7/21
  110. */
  111. public function createSecretKey(int $merId)
  112. {
  113. list($msec, $sec) = explode(' ', microtime());
  114. $msectime = number_format((floatval($msec) + floatval($sec)) * 1000, 0, '', '');
  115. return $merId.'cb'.MD5($msectime . random_int(10000, max(intval($msec * 10000) + 10000, 98369)));
  116. }
  117. /**
  118. * 获取secret_key
  119. * @param $id
  120. * @return array
  121. * @author Qinii
  122. * @day 2023/7/21
  123. */
  124. public function getSecretKey($id)
  125. {
  126. $data = $this->dao->get($id);
  127. return ['secret_key' => $data['secret_key']];
  128. }
  129. /**
  130. * 重置secret_key
  131. * @param $id
  132. * @return int
  133. * @author Qinii
  134. * @day 2023/7/21
  135. */
  136. public function setSecretKey($id,$merId)
  137. {
  138. $data['secret_key'] = $this->createSecretKey($merId);
  139. $data['update_time'] = date('Y-m-d H:i:s',time());
  140. $this->dao->update($id,$data);
  141. return ['secret_key' => $data['secret_key']];
  142. }
  143. /**
  144. * 检查令牌的有效性
  145. *
  146. * 本函数用于验证传入的令牌是否有效,有效意味着该令牌曾在指定时间内被使用过。
  147. * 它首先检查令牌是否存在于缓存中,如果不存在,则抛出一个授权异常。
  148. * 接着,它获取令牌的最后使用时间,并计算令牌是否已过期。如果令牌过期,则同样抛出授权异常。
  149. * 这个过程旨在确保每个请求的令牌都是近期有效的,从而保障系统的安全性。
  150. *
  151. * @param string $token 需要验证的令牌字符串
  152. * @throws AuthException 如果令牌无效或已过期,则抛出授权异常
  153. */
  154. public function checkToken(string $token)
  155. {
  156. // 检查缓存中是否存在指定的令牌
  157. $has = Cache::has('openapi_' . $token);
  158. // 如果令牌不存在于缓存中,则抛出无效令牌异常
  159. if (!$has)
  160. throw new AuthException('无效的token');
  161. // 获取令牌的最后使用时间
  162. $lastTime = Cache::get('openapi_' . $token);
  163. // 计算令牌的有效期,并与当前时间进行比较
  164. // 如果令牌已过期,则抛出令牌过期异常
  165. if (($lastTime + (intval(Config::get('admin.openapi_token_valid_exp', 15))) * 60) < time())
  166. throw new AuthException('token 已过期,请重新登录');
  167. }
  168. }