dd.php 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace app\components\OpenAuth\core;
  3. use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Dingtalk;
  4. use \Exception;
  5. use AlibabaCloud\Tea\Exception\TeaError;
  6. use AlibabaCloud\Tea\Utils\Utils;
  7. use Darabonba\OpenApi\Models\Config;
  8. use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetAccessTokenRequest;
  9. use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetUserTokenRequest;
  10. use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetSsoAccessTokenRequest;
  11. use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetSsoUserInfoHeaders;
  12. use AlibabaCloud\SDK\Dingtalk\Voauth2_1_0\Models\GetSsoUserInfoRequest;
  13. use AlibabaCloud\SDK\Dingtalk\Vcontact_1_0\Dingtalk as Dingtalk_v1;
  14. use AlibabaCloud\SDK\Dingtalk\Vcontact_1_0\Models\GetUserHeaders;
  15. use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
  16. use app\common\helpers\Session;
  17. use Yii;
  18. class DD extends DDOAuth {
  19. function __construct($access_token = NULL, $refresh_token = NULL) {
  20. parent::__construct($access_token, $refresh_token);
  21. }
  22. //成功拿到了token
  23. function verify() {
  24. if (!empty($_SESSION['dd_token'])) {
  25. return true;
  26. } else {
  27. return false;
  28. }
  29. }
  30. }
  31. class DDOAuth {
  32. public $appid;
  33. public $appsecret;
  34. public $access_token;
  35. public $refresh_token;
  36. function __construct($access_token = NULL, $refresh_token = NULL) {
  37. $this->appid = DD_APPKEY;
  38. $this->appsecret = DD_APPSECRET;
  39. $this->access_token = $access_token;
  40. $this->refresh_token = $refresh_token;
  41. }
  42. public static function createClient(){
  43. $config = new Config([]);
  44. $config->protocol = "https";
  45. $config->regionId = "central";
  46. return new Dingtalk($config);
  47. }
  48. //生成授权地址
  49. function authUrl($redirectUrl,$state){
  50. return 'https://login.dingtalk.com/oauth2/auth?redirect_uri='.urlencode($redirectUrl).'&response_type=code&client_id='.$this->appid.'&scope=openid&state='.$state.'&prompt=consent';
  51. }
  52. /*
  53. * 获取token
  54. */
  55. public function getAccessToken($code)
  56. {
  57. //获取个人用户token
  58. $client = self::createClient();
  59. $getUserTokenRequest = new GetUserTokenRequest([
  60. "clientId" => $this->appid,
  61. "clientSecret" => $this->appsecret,
  62. "code" => $code,
  63. "grantType" => "authorization_code"
  64. ]);
  65. try {
  66. $result = $client->getUserToken($getUserTokenRequest);
  67. $accessToken = $result->body->accessToken;
  68. $refreshToken = $result->body->refreshToken;
  69. $expireIn = $result->body->expireIn;
  70. $array = ['access_token'=>$accessToken,'refresh_token'=>$refreshToken,'expires_in'=>$expireIn];
  71. return $array;
  72. }
  73. catch (Exception $err) {
  74. if (!($err instanceof TeaError)) {
  75. $err = new TeaError([], $err->getMessage(), $err->getCode(), $err);
  76. }
  77. if (!Utils::empty_($err->code) && !Utils::empty_($err->message)) {
  78. // err 中含有 code 和 message 属性,可帮助开发定位问题
  79. return ['errcode'=>$err->code,'msg'=>$err->message];
  80. }
  81. }
  82. }
  83. /**
  84. * 个人免登场景签名算法
  85. */
  86. function getSignature($timestamp, $appSecret){
  87. // 根据timestamp, appSecret计算签名值
  88. $s = hash_hmac('sha256', $timestamp, $appSecret, true);
  89. $signature = base64_encode($s);
  90. $urlencode_signature = urlencode($signature);
  91. return $urlencode_signature;
  92. }
  93. /**
  94. * post 请求
  95. * @param $remote_server
  96. * @param $post_string
  97. * @return bool|string
  98. */
  99. function PostCurlRequest($remote_server, $code)
  100. {
  101. $ch = curl_init();
  102. curl_setopt($ch, CURLOPT_URL, $remote_server);
  103. curl_setopt($ch, CURLOPT_POST, 1);
  104. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
  105. curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json;charset=utf-8'));
  106. curl_setopt($ch, CURLOPT_POSTFIELDS, $code);
  107. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  108. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
  109. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
  110. $data = curl_exec($ch);
  111. curl_close($ch);
  112. return $data;
  113. }
  114. //使用扫码登录的临时CODE获取用户信息
  115. public function getUserInfoByCode()
  116. {
  117. $access_key = $this->appid; //应用的AppKey
  118. $app_secret = $this->appsecret; //应用秘钥
  119. $code = json_encode(['tmp_auth_code' => $_GET['code']]); //获取临时code
  120. $time = time() . '000'; //毫秒时间戳
  121. $urlencode_signature = $this->getSignature($time, $app_secret); //签名
  122. //地址组装,获取用户信息
  123. $remote_server = 'https://oapi.dingtalk.com/sns/getuserinfo_bycode?accessKey='. $access_key .'&timestamp=' . $time . '&signature=' . $urlencode_signature;
  124. $json = $this->PostCurlRequest($remote_server, $code);
  125. return $json;
  126. }
  127. }