Applet.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. <?php
  2. namespace Passport\Src;
  3. use Dever;
  4. use Passport\Lib\Base;
  5. # 小程序
  6. class Applet extends Base
  7. {
  8. private $cache = 'applet_sessionKey_';
  9. public function init()
  10. {
  11. $uid = $this->check();
  12. $user = Dever::load('passport/user-one', $uid);
  13. return $user;
  14. }
  15. /**
  16. * 用户绑定 生成用户信息
  17. *
  18. * @return mixed
  19. */
  20. public function bind()
  21. {
  22. $create = Dever::input('create', 3);
  23. $data = $this->getLoginInfo();
  24. if ($create == 1) {
  25. # 直接返回用户信息
  26. $info = Dever::db('passport/wechat')->one(array('openid' => $data['openid']));
  27. $data = array('uid' => false);
  28. if ($info) {
  29. //$user = Dever::db('passport/user')->one($uid);
  30. $data = $this->getSign($info['uid'], $info['id']);
  31. }
  32. } elseif ($create == 2) {
  33. # 未授权,会生成临时用户,针对有的项目,不需要授权,但是还要生成用户
  34. $data = $this->create($data, false);
  35. }
  36. return $data;
  37. }
  38. /**
  39. * 一次性登录:通过code或者openid、sessionkey来注册用户,此时已经授权,可以直接拿到unioinid
  40. *
  41. * @return mixed
  42. */
  43. public function login()
  44. {
  45. $data = array();
  46. $data = $this->getLoginInfo();
  47. $data += $this->getWechatData($data['session_key']);
  48. $data['username'] = Dever::input('nickname');
  49. $data['avatar'] = Dever::input('avatarurl');
  50. $data['sex'] = Dever::input('gender');
  51. $data['city'] = Dever::input('city');
  52. //$data['mobile'] = Dever::input('mobile');
  53. $data['province'] = Dever::input('province');
  54. $data['country'] = Dever::input('country');
  55. $result = $this->create($data);
  56. return $result;
  57. }
  58. /**
  59. * 更新用户信息
  60. *
  61. * @return mixed
  62. */
  63. public function update()
  64. {
  65. $uid = $this->check();
  66. $vid = Dever::input('vid');
  67. $info = Dever::db('passport/user')->one($uid);
  68. if ($info) {
  69. if ($info['temp'] == 1) {
  70. # 针对未授权,生成临时用户的用户进行设置积分
  71. Dever::score($uid, 'bind_wechat', '用户微信授权');
  72. }
  73. $data['temp'] = 2;
  74. $data['username'] = Dever::input('nickname');
  75. $data['avatar'] = Dever::input('avatarurl');
  76. $data['sex'] = Dever::input('gender');
  77. $data['city'] = Dever::input('city');
  78. $data['province'] = Dever::input('province');
  79. $data['country'] = Dever::input('country');
  80. if ($data['sex'] == 1) {
  81. $data['sex'] = 1;
  82. } elseif ($data['sex'] == 2) {
  83. $data['sex'] = 2;
  84. } else {
  85. $data['sex'] = 3;
  86. }
  87. $this->updateUser($uid, $data);
  88. } else {
  89. Dever::alert('无效的用户id,请重新登录');
  90. }
  91. $result = $this->getSign($uid, $vid);
  92. return $result;
  93. }
  94. /**
  95. * 更新用户信息 手机号
  96. *
  97. * @return mixed
  98. */
  99. public function mobile()
  100. {
  101. $uid = $this->check();
  102. $vid = Dever::input('vid');
  103. $result = array();
  104. $mobile = $phoneNumber = '';
  105. $iv = Dever::input('iv');
  106. $encryptedData = Dever::input('encryptedData');
  107. if ($iv && $encryptedData) {
  108. $key = $this->cache . $vid;
  109. $session_key = Dever::cache($key);
  110. if (!$session_key) {
  111. $vinfo = Dever::db('passport/wechat')->one($vid);
  112. $session_key = $vinfo['session_key'];
  113. }
  114. $data = $this->getWechatData($session_key);
  115. if ($data && $data['mobile']) {
  116. $mobile = $data['mobile'];
  117. $phoneNumber = $data['phone'];
  118. }
  119. }
  120. if ($mobile && $phoneNumber && $uid) {
  121. $uid = $this->combine($uid, $mobile, 'mobile');
  122. $info = Dever::load('passport/user-one', $uid);
  123. $result['mobile'] = $mobile;
  124. if ($info) {
  125. if (!$info['mobile']) {
  126. Dever::score($uid, 'bind_mobile', '绑定手机号');
  127. }
  128. $update['mobile'] = $mobile;
  129. $update['bind'] = 1;
  130. $update['where_id'] = $uid;
  131. Dever::db('passport/user')->update($update);
  132. $state = Dever::config('base', 'project')->regSendSms;
  133. if ($state) {
  134. Dever::setInput('skin', $state);
  135. $this->send($mobile, $uid);
  136. }
  137. } else {
  138. Dever::alert('无效的用户id,请重新登录');
  139. }
  140. }
  141. $result['vid'] = $vid;
  142. $result['uid'] = $uid;
  143. $result['signature'] = Dever::login($uid);
  144. //$result = $this->getSign($uid, $vid);
  145. if (isset($update['mobile']) && $update['mobile']) {
  146. $result['mobile'] = $update['mobile'];
  147. }
  148. return $result;
  149. }
  150. /**
  151. * 生成用户,返回uid
  152. *
  153. * @return int
  154. */
  155. public function create($data, $state = true)
  156. {
  157. $uid = false;
  158. $data['system'] = Dever::input('system', 1);
  159. $info = Dever::db('passport/wechat')->one(array('openid' => $data['openid']));
  160. $wechat = array();
  161. if (!$info) {
  162. if (isset($data['unionid']) && $data['unionid']) {
  163. $info = Dever::db('passport/wechat')->one(array('unionid' => $data['unionid']));
  164. if (!$info) {
  165. $uid = false;
  166. } else {
  167. # 判断用户是否存在,是否需要合并
  168. //$uid = $this->combine($info['uid'], $data['unionid']);
  169. $uid = $info['uid'];
  170. }
  171. $wechat['unionid'] = $data['unionid'];
  172. }
  173. if (!$uid) {
  174. $uid = $this->reg('applet', $data);
  175. if ($state) {
  176. Dever::score($info['id'], 'bind_wechat', '用户微信授权');
  177. }
  178. }
  179. $wechat['openid'] = $data['openid'];
  180. $wechat['session_key'] = $data['session_key'];
  181. $wechat['uid'] = $uid;
  182. # 微信小程序
  183. $wechat['type'] = 1;//即将废弃,统一
  184. $wechat['system_source'] = 5;
  185. $wechat['system_id'] = $data['system'];
  186. $id = Dever::db('passport/wechat')->insert($wechat);
  187. $key = $this->cache . $id;
  188. $cache = Dever::cache($key, $data['session_key']);
  189. } else {
  190. $uid = $info['uid'];
  191. $id = $info['id'];
  192. /*
  193. if (isset($data['unionid']) && $data['unionid']) {
  194. # 判断用户是否存在,是否需要合并
  195. $wechat['uid'] = $this->combine($uid, $data['unionid']);
  196. if ($wechat['uid'] != $uid) {
  197. $uid = $wechat['uid'];
  198. }
  199. }
  200. */
  201. $key = $this->cache . $id;
  202. $cache = Dever::cache($key, $data['session_key']);
  203. if (!$cache) {
  204. $wechat['session_key'] = $data['session_key'];
  205. }
  206. if ($wechat) {
  207. $wechat['where_id'] = $id;
  208. Dever::db('passport/wechat')->update($wechat);
  209. }
  210. }
  211. $user = Dever::db('passport/user')->one($uid);
  212. $result = $this->getSign($uid, $id);
  213. if (isset($user['mobile']) && $user['mobile']) {
  214. $result['mobile'] = $user['mobile'];
  215. }
  216. return $result;
  217. }
  218. private function unionid($session_key)
  219. {
  220. $data = $this->decryptData($session_key);
  221. if ($data && isset($data->unionId)) {
  222. return $data->unionId;
  223. }
  224. return false;
  225. }
  226. private function getWechatData($session_key)
  227. {
  228. $result = array();
  229. $data = $this->decryptData($session_key);
  230. $result['openid'] = '';
  231. $result['unionid'] = '';
  232. $result['mobile'] = '';
  233. $result['phone'] = '';
  234. if ($data && isset($data->openId)) {
  235. $result['openid'] = $data->openId;
  236. if (isset($data->unionId)) {
  237. $result['unionid'] = $data->unionId;
  238. }
  239. }
  240. if ($data && isset($data->phoneNumber)) {
  241. if (isset($data->phoneNumber)) {
  242. $result['phone'] = $data->phoneNumber;
  243. }
  244. }
  245. if ($data && isset($data->purePhoneNumber)) {
  246. if (isset($data->purePhoneNumber)) {
  247. $result['mobile'] = $data->purePhoneNumber;
  248. }
  249. }
  250. return $result;
  251. }
  252. private function decryptData($session_key)
  253. {
  254. $iv = Dever::input('iv');
  255. $encryptedData = Dever::input('encryptedData');
  256. if (!$iv || !$encryptedData) {
  257. return false;
  258. }
  259. if (strlen($session_key) != 24) {
  260. return false;
  261. }
  262. if (strlen($iv) != 24) {
  263. return false;
  264. }
  265. $aesKey = base64_decode($session_key);
  266. $aesIV = base64_decode($iv);
  267. $aesCipher = base64_decode($encryptedData);
  268. $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV);
  269. $dataObj = json_decode($result);
  270. if ($dataObj == NULL) {
  271. return false;
  272. }
  273. /*
  274. $applet = Dever::config('base', 'project')->applet;
  275. $appid = $applet['appid'];
  276. if($dataObj->watermark->appid != $appid) {
  277. return false;
  278. }*/
  279. return $dataObj;
  280. }
  281. private function getApplet()
  282. {
  283. $applet = Dever::config('base', 'project')->applet;
  284. $project = false;
  285. $system = Dever::input('system', 1);
  286. if (Dever::project('token')) {
  287. $project = Dever::db('token/project')->one($system);
  288. }
  289. if (!$project) {
  290. if (isset($applet['project']) && $applet['project']) {
  291. $project = Dever::db($applet['project'])->one($system);
  292. }
  293. }
  294. if ($project) {
  295. $applet['appid'] = $project['appid'];
  296. $applet['secret'] = $project['secret'];
  297. }
  298. if (!$applet || !$applet['appid'] || !$applet['secret']) {
  299. Dever::alert('错误的appid');
  300. }
  301. return $applet;
  302. }
  303. private function getLoginInfo()
  304. {
  305. $session_key = Dever::input('session_key');
  306. if ($session_key) {
  307. return array('session_key' => $session_key, 'openid' => $openid);
  308. }
  309. $applet = $this->getApplet();
  310. $appid = $applet['appid'];
  311. $secret = $applet['secret'];
  312. $url = $applet['url'];
  313. $code = Dever::input('code');
  314. if (!$applet || !$applet['appid'] || !$applet['secret']) {
  315. Dever::alert('错误的appid');
  316. }
  317. $url .= '?appid=' . $appid;
  318. $url .= '&secret=' . $secret;
  319. $url .= '&js_code=' . $code;
  320. $url .= '&grant_type=authorization_code';
  321. $data = Dever::curl($url);
  322. Dever::log($data, 'passport_applet');
  323. if (strstr($data, 'errcode')) {
  324. Dever::alert($data);
  325. }
  326. //YzJkOThpRFhwZ1lQTF9mZl9hLVZjZnFXemJVenlYcDQ3d3JWekk0b1I4NjBBQ0Naejg4a0VQa0U=
  327. //$data = '{"session_key":"aNAXk7nG\/DRYI\/G0KzJRsw==","openid":"oIZ895RZs2ZkywasoZIv6WavPZlQ"}';
  328. $data = Dever::json_decode($data);
  329. return $data;
  330. }
  331. }