common.php 6.0 KB

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