Applet.php 12 KB

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