PageRenderTime 39ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/models/openid/google.php

https://gitlab.com/Ltaimao/wecenter
PHP | 338 lines | 248 code | 78 blank | 12 comment | 26 complexity | e8fbde598ada3a4c3093e9caddb90384 MD5 | raw file
  1. <?php
  2. /*
  3. +--------------------------------------------------------------------------
  4. | WeCenter [#RELEASE_VERSION#]
  5. | ========================================
  6. | by WeCenter Software
  7. | © 2011 - 2014 WeCenter. All Rights Reserved
  8. | http://www.wecenter.com
  9. | ========================================
  10. | Support: WeCenter@qq.com
  11. |
  12. +---------------------------------------------------------------------------
  13. */
  14. if (!defined('IN_ANWSION'))
  15. {
  16. die;
  17. }
  18. class openid_google_class extends AWS_MODEL
  19. {
  20. const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
  21. const OAUTH2_TOKEN_URL = 'https://accounts.google.com/o/oauth2/token';
  22. const OAUTH2_TOKEN_VALIDATION_URL = 'https://www.googleapis.com/oauth2/v2/tokeninfo';
  23. const OAUTH2_USER_INFO_URL = 'https://www.googleapis.com/oauth2/v2/userinfo';
  24. public $authorization_code;
  25. public $access_token;
  26. public $redirect_url;
  27. public $refresh_token;
  28. public $expires_time;
  29. public $error_msg;
  30. public $user_info;
  31. public function get_redirect_url($redirect_url, $state = null)
  32. {
  33. $args = array(
  34. 'client_id' => get_setting('google_client_id'),
  35. 'redirect_uri' => get_js_url($redirect_url),
  36. 'response_type' => 'code',
  37. 'scope' => 'profile email'
  38. );
  39. if ($state)
  40. {
  41. $args['state'] = $state;
  42. }
  43. return self::OAUTH2_AUTH_URL . '?' . http_build_query($args);
  44. }
  45. public function oauth2_login()
  46. {
  47. if (!$this->get_access_token() OR !$this->validate_access_token() OR !$this->get_user_info())
  48. {
  49. if (!$this->error_msg)
  50. {
  51. $this->error_msg = AWS_APP::lang()->_t('Google 登录失败');
  52. }
  53. return false;
  54. }
  55. return true;
  56. }
  57. public function get_access_token()
  58. {
  59. if (!$this->authorization_code)
  60. {
  61. $this->error_msg = AWS_APP::lang()->_t('authorization code 为空');
  62. return false;
  63. }
  64. $args = array(
  65. 'client_id' => get_setting('google_client_id'),
  66. 'client_secret' => get_setting('google_client_secret'),
  67. 'code' => $this->authorization_code,
  68. 'grant_type' => 'authorization_code',
  69. 'redirect_uri' => get_js_url($this->redirect_url)
  70. );
  71. $result = HTTP::request(self::OAUTH2_TOKEN_URL, 'POST', $args);
  72. if (!$result)
  73. {
  74. $this->error_msg = AWS_APP::lang()->_t('获取 access token 时,与 Google 通信失败');
  75. return false;
  76. }
  77. $result = json_decode($result, true);
  78. if ($result['error'])
  79. {
  80. if (!$result['error_description'])
  81. {
  82. $result['error_description'] = $result['error'];
  83. }
  84. $this->error_msg = AWS_APP::lang()->_t('获取 access token 失败,错误为:%s', $result['error_description']);
  85. return false;
  86. }
  87. $this->access_token = $result['access_token'];
  88. $this->refresh_token = $result['refresh_token'];
  89. return true;
  90. }
  91. public function validate_access_token()
  92. {
  93. if (!$this->access_token)
  94. {
  95. $this->error_msg = AWS_APP::lang()->_t('access token 为空');
  96. }
  97. $result = curl_get_contents(self::OAUTH2_TOKEN_VALIDATION_URL . '?access_token=' . $this->access_token);
  98. if (!$result)
  99. {
  100. $this->error_msg = AWS_APP::lang()->_t('验证 access token 时,与 Google 通信失败');
  101. }
  102. $result = json_decode($result, true);
  103. if ($result['error_description'])
  104. {
  105. $this->error_msg = AWS_APP::lang()->_t('验证 access token 失败,错误为:%s', $result['error_description']);
  106. }
  107. $this->expires_time = time() + intval($result['expires_in']);
  108. return true;
  109. }
  110. public function get_user_info()
  111. {
  112. if (!$this->access_token)
  113. {
  114. $this->error_msg = AWS_APP::lang()->_t('access token 为空');
  115. return false;
  116. }
  117. $header = array('Authorization: Bearer ' . $this->access_token);
  118. $result = HTTP::request(self::OAUTH2_USER_INFO_URL, 'GET', null, 10, $header);
  119. if (!$result)
  120. {
  121. $this->error_msg = AWS_APP::lang()->_t('获取个人资料时,与 Google 通信失败');
  122. return false;
  123. }
  124. $result = json_decode($result, true);
  125. if ($result['error'])
  126. {
  127. $this->error_msg = AWS_APP::lang()->_t('获取个人资料失败,错误为:%s', $result['error']['message']);
  128. return false;
  129. }
  130. $this->user_info = array(
  131. 'id' => $result['id'],
  132. 'name' => $result['name'],
  133. 'locale' => $result['locale'],
  134. 'picture' => $result['picture'],
  135. 'gender' => $result['gender'],
  136. 'email' => $result['email'],
  137. 'link' => $result['link'],
  138. 'verified_email' => $result['verified_email'],
  139. 'authorization_code' => $this->authorization_code,
  140. 'access_token' => $this->access_token,
  141. 'refresh_token' => $this->refresh_token,
  142. 'expires_time' => $this->expires_time
  143. );
  144. return true;
  145. }
  146. public function refresh_access_token($uid)
  147. {
  148. $user_info = $this->get_google_user_by_uid($uid);
  149. if (!$user_info)
  150. {
  151. $this->error_msg = AWS_APP::lang()->_t('Google 账号未绑定');
  152. return false;
  153. }
  154. if (!$user_info['refresh_token'])
  155. {
  156. $this->error_msg = AWS_APP::lang()->_t('refresh token 为空');
  157. return false;
  158. }
  159. $args = array(
  160. 'client_id' => get_setting('google_client_id'),
  161. 'client_secret' => get_setting('google_client_secret'),
  162. 'refresh_token' => htmlspecialchars_decode($user_info['refresh_token']),
  163. 'grant_type' => 'refresh_token'
  164. );
  165. $result = HTTP::request(self::OAUTH2_TOKEN_URL, 'POST', $args);
  166. if (!$result)
  167. {
  168. $this->error_msg = AWS_APP::lang()->_t('更新 access token 时,与 Google 通信失败');
  169. return false;
  170. }
  171. $result = json_decode($result, true);
  172. if ($result['error'])
  173. {
  174. if (!$result['error_description'])
  175. {
  176. $result['error_description'] = $result['error'];
  177. }
  178. $this->error_msg = AWS_APP::lang()->_t('更新 access token 失败,错误为:%s', $result['error_description']);
  179. return false;
  180. }
  181. $this->update('users_google', array(
  182. 'access_token' => htmlspecialchars($result['access_token']),
  183. 'expires_time' => time() + intval($result['expires_in'])
  184. ), 'id = ' . $user_info['id']);
  185. return true;
  186. }
  187. public function bind_account($google_user, $uid)
  188. {
  189. if ($this->get_google_user_by_id($google_user['id']) OR $this->get_google_user_by_uid($uid))
  190. {
  191. return false;
  192. }
  193. return $this->insert('users_google', array(
  194. 'id' => htmlspecialchars($google_user['id']),
  195. 'uid' => intval($uid),
  196. 'name' => htmlspecialchars($google_user['name']),
  197. 'locale' => htmlspecialchars($google_user['locale']),
  198. 'picture' => htmlspecialchars($google_user['picture']),
  199. 'gender' => htmlspecialchars($google_user['gender']),
  200. 'email' => htmlspecialchars($google_user['email']),
  201. 'link' => htmlspecialchars($google_user['link']),
  202. 'access_token' => htmlspecialchars($google_user['access_token']),
  203. 'refresh_token' => htmlspecialchars($google_user['refresh_token']),
  204. 'expires_time' => intval($google_user['expires_time']),
  205. 'add_time' => time()
  206. ));
  207. }
  208. public function update_user_info($id, $google_user)
  209. {
  210. if (!is_digits($id))
  211. {
  212. return false;
  213. }
  214. return $this->update('users_google', array(
  215. 'name' => htmlspecialchars($google_user['name']),
  216. 'locale' => htmlspecialchars($google_user['locale']),
  217. 'picture' => htmlspecialchars($google_user['picture']),
  218. 'gender' => htmlspecialchars($google_user['gender']),
  219. 'email' => htmlspecialchars($google_user['email']),
  220. 'link' => htmlspecialchars($google_user['link']),
  221. 'access_token' => htmlspecialchars($google_user['access_token']),
  222. 'refresh_token' => htmlspecialchars($google_user['refresh_token']),
  223. 'expires_time' => intval($google_user['expires_time'])
  224. ), 'id = ' . $id);
  225. }
  226. public function unbind_account($uid)
  227. {
  228. if (!is_digits($uid))
  229. {
  230. return false;
  231. }
  232. return $this->delete('users_google', 'uid = ' . $uid);
  233. }
  234. public function get_google_user_by_id($id)
  235. {
  236. if (!is_digits($id))
  237. {
  238. return false;
  239. }
  240. static $google_user_info;
  241. if (!$google_user_info[$id])
  242. {
  243. $google_user_info[$id] = $this->fetch_row('users_google', 'id = ' . $id);
  244. }
  245. return $google_user_info[$id];
  246. }
  247. public function get_google_user_by_uid($uid)
  248. {
  249. if (!is_digits($uid))
  250. {
  251. return false;
  252. }
  253. static $google_user_info;
  254. if (!$google_user_info[$uid])
  255. {
  256. $google_user_info[$uid] = $this->fetch_row('users_google', 'uid = ' . $uid);
  257. }
  258. return $google_user_info[$uid];
  259. }
  260. }