DrbService.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. namespace App\Service;
  3. use Illuminate\Support\Facades\Redis;
  4. class DrbService extends Service
  5. {
  6. const RedisKey = 'DRBACCESSTOKENKEY';
  7. public function getAccessToken()
  8. {
  9. $token = Redis::get(self::RedisKey);
  10. if(! empty($token)) return [true, ['access_token' => $token]];
  11. $appKey = config('dingtalk.app_key');
  12. $appSecret = config('dingtalk.app_secret');
  13. $url = "https://api.dingtalk.com/v1.0/oauth2/accessToken";
  14. $resp = $this->curlOpen1($url, [
  15. 'request' => 'post',
  16. 'header' => ['Content-Type: application/json'],
  17. 'json' => [
  18. "appKey" => $appKey,
  19. "appSecret" => $appSecret
  20. ]
  21. ]);
  22. $res = json_decode($resp, true);
  23. $accessToken = $res['accessToken'] ?? "";
  24. $expires_in = $res['expires_in'] ?? 0;
  25. if(empty($accessToken)) return [false, 'AccessToken获取失败'];
  26. Redis::setex(self::RedisKey, $expires_in, $accessToken);
  27. return [true, ['access_token' => $accessToken]];
  28. }
  29. /**
  30. * 根据前端传来的免登 code 获取用户信息
  31. * @param string $code 前端 dd.getAuthCode 获取的 code
  32. * @return array [bool, data] bool 表示成功与否,data 成功返回用户信息,失败返回错误信息
  33. */
  34. public function getUserByCode(string $code)
  35. {
  36. if (empty($code)) return [false, '钉钉授权code不能为空'];
  37. // 1. 获取 access_token
  38. [$success, $tokenData] = $this->getAccessToken();
  39. if (! $success) return [false, $tokenData]; // tokenData 是错误信息
  40. $accessToken = $tokenData['access_token'];
  41. // 2. 用 code 换取用户信息(v2 接口)
  42. $url = "https://oapi.dingtalk.com/topapi/v2/user/getuserinfo?access_token={$accessToken}";
  43. $resp = $this->curlOpen1($url, [
  44. 'request' => 'post',
  45. 'header' => [
  46. "Content-Type: application/json",
  47. ],
  48. 'json' => [
  49. "code" => $code
  50. ]
  51. ]);
  52. $res = json_decode($resp, true);
  53. if (!isset($res['errcode'])) {
  54. return [false, '接口返回异常: ' . $resp];
  55. }
  56. if ($res['errcode'] !== 0) {
  57. return [false, '获取用户信息失败: ' . $res['errmsg']];
  58. }
  59. // v2 接口返回的是 result.user_id
  60. $userid = $res['result']['user_id'] ?? null;
  61. if (!$userid) {
  62. return [false, '获取userid失败'];
  63. }
  64. return [true, $res];
  65. }
  66. protected function curlOpen1($url, $config = [])
  67. {
  68. $default = [
  69. 'post' => false,
  70. 'request' => 'get',
  71. 'header' => [],
  72. 'json' => null,
  73. 'timeout' => 30
  74. ];
  75. $arr = array_merge($default, $config);
  76. $ch = curl_init();
  77. curl_setopt($ch, CURLOPT_URL, $url);
  78. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  79. curl_setopt($ch, CURLOPT_TIMEOUT, $arr['timeout']);
  80. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
  81. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  82. if (!empty($arr['header'])) {
  83. curl_setopt($ch, CURLOPT_HTTPHEADER, $arr['header']);
  84. }
  85. if ($arr['post'] || $arr['request'] !== 'get') {
  86. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, strtoupper($arr['request']));
  87. if ($arr['json'] !== null) {
  88. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($arr['json'], JSON_UNESCAPED_UNICODE));
  89. }
  90. }
  91. $result = curl_exec($ch);
  92. if ($result === false) {
  93. $err = curl_error($ch);
  94. curl_close($ch);
  95. return json_encode(['error' => $err]);
  96. }
  97. curl_close($ch);
  98. return $result;
  99. }
  100. }