common.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. <?php
  2. use Firebase\JWT\JWT;
  3. use Firebase\JWT\Key;
  4. /// 加密密钥
  5. $GLOBALS['token_key_secret'] = "z.1i8L?Ld+ovuA4r%4YZrz?w1Y%-NYvlrJ=TqV$[W[5=B#C[=l2gHV8gJ,DhZc";
  6. /// COOKIE 有效期
  7. $GLOBALS['cookieExpire'] = 60 * 60 * 24 * 7;
  8. /**
  9. * 响应成功json
  10. */
  11. if(!function_exists('json_success')){
  12. function json_success($data = [], $message = ""){
  13. return json([
  14. 'state' => 1,
  15. 'data' => $data,
  16. 'message' => $message ?? ""
  17. ]);
  18. }
  19. }
  20. /**
  21. * 响应失败json
  22. */
  23. if(!function_exists('json_error')){
  24. function json_error($data = [], $message = "", $code = 1){
  25. return json([
  26. 'state' => 0,
  27. 'code' => $code,
  28. 'data' => $data,
  29. 'message' => $message ?? ""
  30. ]);
  31. }
  32. }
  33. /**
  34. * 获取用户真实请求IP
  35. * 使用ThinkPHP内置的Request::ip()方法
  36. *
  37. * @return string 返回客户端真实IP地址
  38. */
  39. if(!function_exists('getClientIp')){
  40. function getClientIp() {
  41. return \think\facade\Request::ip();
  42. }
  43. }
  44. /**
  45. * 生成JWT Token
  46. *
  47. * @param array $data 待加密数据
  48. * @param int $expire 过期时间(秒),0表示使用默认过期时间
  49. * @return string
  50. */
  51. if(!function_exists('generateToken')){
  52. function generateToken($data = [], $expire = 0){
  53. $payload = [
  54. 'exp' => time() + ($expire > 0 ? $expire : $GLOBALS['cookieExpire']), // 有效期
  55. 'iat' => time(), // 签发时间
  56. ];
  57. $payload = array_merge($payload, $data);
  58. $token = JWT::encode($payload, $GLOBALS['token_key_secret'], 'HS256');
  59. return $token;
  60. }
  61. }
  62. /**
  63. * 解析JWT Token
  64. *
  65. * @param string $token JWT Token字符串
  66. * @return array|null 解析成功返回payload数组,失败返回null
  67. */
  68. if(!function_exists('parseToken')){
  69. function parseToken($token) {
  70. try {
  71. if (empty($token)) {
  72. return null;
  73. }
  74. // 使用JWT库解析token
  75. $decoded = JWT::decode($token, new Key($GLOBALS['token_key_secret'], 'HS256'));
  76. // 转换为数组
  77. $payload = (array) $decoded;
  78. // 检查是否过期
  79. if (isset($payload['exp']) && $payload['exp'] < time()) {
  80. return null;
  81. }
  82. return $payload;
  83. } catch (\Firebase\JWT\ExpiredException $e) {
  84. // Token已过期
  85. return null;
  86. } catch (\Firebase\JWT\SignatureInvalidException $e) {
  87. // 签名无效
  88. return null;
  89. } catch (\Firebase\JWT\BeforeValidException $e) {
  90. // Token尚未生效
  91. return null;
  92. } catch (\Exception $e) {
  93. // 其他异常
  94. return null;
  95. }
  96. }
  97. }
  98. /**
  99. * 验证Token是否有效
  100. *
  101. * @param string $token JWT Token字符串
  102. * @return bool
  103. */
  104. if(!function_exists('verifyToken')){
  105. function verifyToken($token) {
  106. return parseToken($token) !== null;
  107. }
  108. }
  109. /**
  110. * 检查用户登录状态
  111. *
  112. * @return array|null 登录成功返回用户信息数组,失败返回null
  113. */
  114. if(!function_exists('checkUserLogin')){
  115. function checkUserLogin() {
  116. $token = \think\facade\Cookie::get('auth_token');
  117. if (!$token) {
  118. return null;
  119. }
  120. return parseToken($token);
  121. }
  122. }
  123. /**
  124. * 检查用户权限
  125. *
  126. * @param array $user 用户信息数组
  127. * @param string $controller 控制器名称
  128. * @param string $action 操作名称
  129. * @param bool $checkIp 是否检查IP白名单,默认false
  130. * @return bool 有权限返回true,无权限返回false
  131. */
  132. if(!function_exists('checkPermission')){
  133. function checkPermission($user, $controller, $action, $checkIp = false) {
  134. // 超级管理员拥有所有权限
  135. $superAdminRoleId = \think\facade\Config::get('permission.super_admin_role_id', 1);
  136. if ($user['user_role'] == $superAdminRoleId) {
  137. // 即使是超级管理员,如果需要检查IP,也要验证
  138. if ($checkIp) {
  139. return checkUserIpWhiteList($user);
  140. }
  141. return true;
  142. }
  143. // 获取用户角色权限
  144. $role = \app\model\UserRoleModel::getRoleById($user['user_role'], $user['merchant_id']);
  145. if (!$role) {
  146. return false;
  147. }
  148. $privileges = $role->privileges;
  149. // 检查是否有对应权限
  150. $hasPermission = isset($privileges[$controller]) &&
  151. is_array($privileges[$controller]) &&
  152. in_array($action, $privileges[$controller]);
  153. // 如果有权限且需要检查IP,则进一步验证IP白名单
  154. if ($hasPermission && $checkIp) {
  155. return checkUserIpWhiteList($user);
  156. }
  157. return $hasPermission;
  158. }
  159. }
  160. /**
  161. * 检查用户IP白名单
  162. *
  163. * @param array $user 用户信息数组
  164. * @return bool IP在白名单中返回true,否则返回false
  165. */
  166. if(!function_exists('checkUserIpWhiteList')){
  167. function checkUserIpWhiteList($user) {
  168. // 获取用户完整信息
  169. $userModel = \app\model\UserModel::where('user_id', $user['user_id'])
  170. ->where('merchant_id', $user['merchant_id'])
  171. ->find();
  172. if (!$userModel) {
  173. return false;
  174. }
  175. // 获取客户端IP
  176. $clientIp = getClientIp();
  177. // 检查IP白名单
  178. return \app\service\IpWhiteListService::checkIpWhiteList($clientIp, $userModel->white_list_ip);
  179. }
  180. }
  181. /**
  182. * 检查用户登录状态并验证IP白名单
  183. *
  184. * @param bool $checkIp 是否检查IP白名单,默认false
  185. * @return array|null 验证通过返回用户信息数组,失败返回null
  186. */
  187. if(!function_exists('checkUserLoginWithIp')){
  188. function checkUserLoginWithIp($checkIp = false) {
  189. $user = checkUserLogin();
  190. if (!$user) {
  191. return null;
  192. }
  193. // 如果需要检查IP白名单
  194. if ($checkIp && !checkUserIpWhiteList($user)) {
  195. return null;
  196. }
  197. return $user;
  198. }
  199. }