Login.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. <?php
  2. /**
  3. * Index.php
  4. * Niushop商城系统 - 团队十年电商经验汇集巨献!
  5. * =========================================================
  6. * Copy right 2015-2025 杭州牛之云科技有限公司, 保留所有权利。
  7. * ----------------------------------------------
  8. * 官方网址: https://www.niushop.com
  9. * =========================================================
  10. * @author : niuteam
  11. * @date : 2022.8.8
  12. * @version : v5.0.0.1
  13. */
  14. namespace app\api\controller;
  15. use app\model\member\Login as LoginModel;
  16. use app\model\message\Message;
  17. use app\model\member\Register as RegisterModel;
  18. use Exception;
  19. use think\facade\Cache;
  20. use app\model\member\Config as ConfigModel;
  21. use app\model\web\Config;
  22. use think\facade\Session;
  23. class Login extends BaseApi
  24. {
  25. #can_receive_registergift 判断新人礼
  26. /**
  27. * 登录方法
  28. */
  29. public function login()
  30. {
  31. $config = new ConfigModel();
  32. $config_info = $config->getRegisterConfig($this->site_id, 'shop');
  33. if (strstr($config_info[ 'data' ][ 'value' ][ 'login' ], 'username') === false) return $this->response($this->error([], "用户名登录未开启!"));
  34. // $auth_info = Session::get("auth_info");
  35. // if (!empty($auth_info)) {
  36. // $this->params = array_merge($this->params, $auth_info);
  37. // }
  38. // 校验验证码
  39. $config_model = new Config();
  40. $info = $config_model->getCaptchaConfig();
  41. if ($info[ 'data' ][ 'value' ][ 'shop_reception_login' ] == 1) {
  42. $captcha = new Captcha();
  43. $check_res = $captcha->checkCaptcha();
  44. if ($check_res[ 'code' ] < 0) return $this->response($check_res);
  45. }
  46. // 登录
  47. $login = new LoginModel();
  48. if (empty($this->params[ "password" ]))
  49. return $this->response($this->error([], "密码不可为空!"));
  50. $res = $login->login($this->params);
  51. //生成access_token
  52. if ($res[ 'code' ] >= 0) {
  53. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  54. return $this->response($this->success([ 'token' => $token, 'can_receive_registergift' => $res[ 'data' ][ 'can_receive_registergift' ] ]));
  55. }
  56. return $this->response($res);
  57. }
  58. /**
  59. * 第三方登录
  60. */
  61. public function auth()
  62. {
  63. $login = new LoginModel();
  64. $res = $login->authLogin($this->params);
  65. //生成access_token
  66. if ($res[ 'code' ] >= 0) {
  67. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  68. $data = [
  69. 'token' => $token,
  70. 'can_receive_registergift' => $res[ 'data' ][ 'can_receive_registergift' ]
  71. ];
  72. if (isset($res[ 'data' ][ 'is_register' ])) $data[ 'is_register' ] = 1;
  73. return $this->response($this->success($data));
  74. }
  75. return $this->response($res);
  76. }
  77. /**
  78. * 授权登录仅登录
  79. * @return false|string
  80. */
  81. public function authOnlyLogin()
  82. {
  83. $login = new LoginModel();
  84. $res = $login->authOnlyLogin($this->params);
  85. //生成access_token
  86. if ($res[ 'code' ] >= 0) {
  87. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  88. $data = [
  89. 'token' => $token,
  90. ];
  91. return $this->response($this->success($data));
  92. }
  93. return $this->response($res);
  94. }
  95. /**
  96. * 检测openid是否存在
  97. */
  98. public function openidIsExits()
  99. {
  100. $login = new LoginModel();
  101. $res = $login->openidIsExits($this->params);
  102. return $this->response($res);
  103. }
  104. /**
  105. * 手机动态码登录
  106. */
  107. public function mobile()
  108. {
  109. $config = new ConfigModel();
  110. $config_info = $config->getRegisterConfig($this->site_id, 'shop');
  111. if (strstr($config_info[ 'data' ][ 'value' ][ 'login' ], 'mobile') === false) return $this->response($this->error([], "动态码登录未开启!"));
  112. $key = $this->params[ 'key' ];
  113. $verify_data = Cache::get($key);
  114. if (!empty($verify_data) && $verify_data[ "mobile" ] == $this->params[ "mobile" ] && $verify_data[ "code" ] == $this->params[ "code" ]) {
  115. $register = new RegisterModel();
  116. $exist = $register->mobileExist($this->params[ "mobile" ], $this->site_id);
  117. if ($exist) {
  118. $login = new LoginModel();
  119. $res = $login->mobileLogin($this->params);
  120. if ($res[ 'code' ] >= 0) {
  121. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  122. $res = $this->success([ 'token' => $token, 'can_receive_registergift' => $res[ 'data' ][ 'can_receive_registergift' ] ]);
  123. }
  124. } else {
  125. $res = $this->error("", "该手机号未注册");
  126. }
  127. } else {
  128. $res = $this->error("", "手机动态码不正确");
  129. }
  130. return $this->response($res);
  131. }
  132. /**
  133. * 微信公众号登录 新增2021.06.18
  134. * captcha_id 验证码id
  135. * captcha_code 验证码
  136. * mobile 手机号码
  137. * code 手机验证码
  138. */
  139. public function wechatLogin()
  140. {
  141. //校验验证码
  142. $captcha = new Captcha();
  143. $check_res = $captcha->checkCaptcha();
  144. if ($check_res[ 'code' ] < 0) return $this->response($check_res);
  145. $auth_info = Session::get("auth_info");
  146. if (!empty($auth_info)) {
  147. $this->params = array_merge($this->params, $auth_info);
  148. }
  149. $key = $this->params[ 'key' ];
  150. $verify_data = Cache::get($key);
  151. //判断手机验证码
  152. if ($verify_data[ "mobile" ] == $this->params[ "mobile" ] && $verify_data[ "code" ] == $this->params[ "code" ]) {
  153. $register = new RegisterModel();
  154. $exist = $register->mobileExist($this->params[ "mobile" ], $this->site_id);
  155. if ($exist) {
  156. //手机号码存在绑定wx_openid并登录
  157. //绑定openid 如果该手机号有openid直接替换
  158. $member_id = $register->getMemberId($this->params[ "mobile" ], $this->site_id);
  159. $res = $register->wxopenidBind([ 'wx_openid' => $this->params[ 'wx_openid' ], 'member_id' => $member_id, 'site_id' => $this->site_id ]);
  160. if ($res[ 'code' ] >= 0) {
  161. $login = new LoginModel();
  162. $res = $login->mobileLogin($this->params);
  163. if ($res[ 'code' ] >= 0) {
  164. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  165. $res = $this->success([ 'token' => $token, 'can_receive_registergift' => $res[ 'data' ][ 'can_receive_registergift' ] ]);
  166. }
  167. }
  168. } else {
  169. //获取存放的缓存推荐人id
  170. $source_member = Session::get('source_member') ?? 0;
  171. if ($source_member > 0) {
  172. $this->params[ 'source_member' ] = $source_member;
  173. }
  174. //手机号码不存在注册账号
  175. $res = $register->mobileRegister($this->params);
  176. if ($res[ 'code' ] >= 0) {
  177. $token = $this->createToken($res[ 'data' ]);
  178. $res = $this->success([ 'token' => $token ]);
  179. }
  180. }
  181. } else {
  182. $res = $this->error("", "手机动态码不正确");
  183. }
  184. return $this->response($res);
  185. }
  186. /**
  187. * 获取手机号登录验证码
  188. * @throws Exception
  189. */
  190. public function mobileCode()
  191. {
  192. // 校验验证码
  193. $config_model = new Config();
  194. $info = $config_model->getCaptchaConfig();
  195. if ($info[ 'data' ][ 'value' ][ 'shop_reception_login' ] == 1) {
  196. $captcha = new Captcha();
  197. $check_res = $captcha->checkCaptcha(false);
  198. if ($check_res[ 'code' ] < 0) return $this->response($check_res);
  199. }
  200. $mobile = $this->params[ 'mobile' ];
  201. if (empty($mobile)) return $this->response($this->error([], "手机号不可为空!"));
  202. $register = new RegisterModel();
  203. $exist = $register->mobileExist($this->params[ "mobile" ], $this->site_id);
  204. if (!$exist) return $this->response($this->error([], "该手机号未注册!"));
  205. $code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数,左侧补0
  206. $message_model = new Message();
  207. $res = $message_model->sendMessage([ 'type' => 'code', "mobile" => $mobile, "site_id" => $this->site_id, "support_type" => [ 'sms' ], "code" => $code, "keywords" => "LOGIN_CODE" ]);
  208. if ($res[ "code" ] >= 0) {
  209. //将验证码存入缓存
  210. $key = 'login_mobile_code_' . md5(uniqid(null, true));
  211. Cache::tag("login_mobile_code")->set($key, [ 'mobile' => $mobile, 'code' => $code ], 600);
  212. return $this->response($this->success([ "key" => $key ]));
  213. } else {
  214. return $this->response($res);
  215. }
  216. }
  217. /**
  218. * 获取第三方首次扫码登录绑定/注册手机号码验证码 手机号码存不存在都可以发送 新增2021.06.18
  219. * captcha_id 验证码id
  220. * captcha_code 验证码
  221. * mobile 手机号码
  222. */
  223. public function getMobileCode()
  224. {
  225. // 校验验证码 start
  226. $captcha = new Captcha();
  227. $check_res = $captcha->checkCaptcha(false);
  228. if ($check_res[ 'code' ] < 0) return $this->response($check_res);
  229. // 校验验证码 end
  230. $mobile = $this->params[ 'mobile' ];
  231. if (empty($mobile)) return $this->response($this->error([], "手机号不可为空!"));
  232. $register = new RegisterModel();
  233. $exist = $register->mobileExist($this->params[ "mobile" ], $this->site_id);
  234. //判断该手机号码是否已绑定wx_openid
  235. // $opneid_exist = $register->openidExist($this->params["mobile"], $this->site_id);
  236. // if ($opneid_exist) return $this->response($this->error([], "该手机号已绑定其他微信公众号!"));
  237. if ($exist) {
  238. $keywords = 'LOGIN_CODE';
  239. } else {
  240. $keywords = 'REGISTER_CODE';
  241. }
  242. $code = str_pad(random_int(1, 9999), 4, 0, STR_PAD_LEFT);// 生成4位随机数,左侧补0
  243. $message_model = new Message();
  244. $res = $message_model->sendMessage([ 'type' => 'code', "mobile" => $mobile, "site_id" => $this->site_id, "support_type" => [ 'sms' ], "code" => $code, "keywords" => $keywords ]);
  245. if ($res[ "code" ] >= 0) {
  246. // if ($res["code"]) {
  247. //将验证码存入缓存
  248. $key = 'login_mobile_code_' . md5(uniqid(null, true));
  249. Cache::tag("login_mobile_code")->set($key, [ 'mobile' => $mobile, 'code' => $code ], 600);
  250. return $this->response($this->success([ "key" => $key ]));
  251. // return $this->response($this->success(["key" => $key,"code"=>$code]));
  252. } else {
  253. return $this->response($res);
  254. }
  255. }
  256. /**
  257. * 手机号授权登录
  258. */
  259. public function mobileAuth()
  260. {
  261. $decrypt_data = event('DecryptData', $this->params, true);
  262. if ($decrypt_data[ 'code' ] < 0) return $this->response($decrypt_data);
  263. $this->params[ 'mobile' ] = $decrypt_data[ 'data' ][ 'purePhoneNumber' ];
  264. $register = new RegisterModel();
  265. $exist = $register->mobileExist($this->params[ "mobile" ], $this->site_id);
  266. if ($exist) {
  267. $login = new LoginModel();
  268. $res = $login->mobileLogin($this->params);
  269. if ($res[ 'code' ] >= 0) {
  270. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  271. $res = $this->success([ 'token' => $token ]);
  272. }
  273. } else {
  274. $res = $register->mobileRegister($this->params);
  275. if ($res[ 'code' ] >= 0) {
  276. $token = $this->createToken($res[ 'data' ]);
  277. $res = $this->success([ 'token' => $token ]);
  278. }
  279. }
  280. return $this->response($res);
  281. }
  282. /**
  283. * 验证token有效性
  284. */
  285. public function verifyToken()
  286. {
  287. $token = $this->checkToken();
  288. if ($token[ 'code' ] < 0) return $this->response($token);
  289. return $this->response($this->success());
  290. }
  291. /**
  292. * 检测登录
  293. * @return false|string
  294. */
  295. public function checkLogin()
  296. {
  297. $key = $this->params[ 'key' ];
  298. $cache = Cache::get('wechat_' . $key);
  299. if (!empty($cache)) {
  300. if (isset($cache[ 'openid' ]) && !empty($cache[ 'openid' ])) {
  301. $login = new LoginModel();
  302. $data = [
  303. 'wx_openid' => $cache[ 'openid' ],
  304. 'site_id' => $this->site_id
  305. ];
  306. $is_exits = $login->openidIsExits($data);
  307. if ($is_exits[ 'data' ]) {
  308. // 存在即登录
  309. $res = $login->authLogin($data);
  310. //生成access_token
  311. if ($res[ 'code' ] >= 0) {
  312. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  313. // Session::set($this->params[ 'app_type' ] . "_token_" . $this->site_id, $token);
  314. // Session::set($this->params[ 'app_type' ] . "_member_id_" . $this->site_id, $res[ 'data' ][ 'member_id' ]);
  315. return $this->response($this->success([ 'token' => $token, 'can_receive_registergift' => $res[ 'data' ][ 'can_receive_registergift' ] ]));
  316. }
  317. return $this->response($res);
  318. } else {
  319. // 将openid存入session
  320. Session::set("auth_info", [
  321. 'wx_openid' => $cache[ 'openid' ],
  322. 'nickname' => $cache[ 'nickname' ],
  323. 'headimg' => $cache[ 'headimgurl' ]
  324. ]);
  325. $config = new ConfigModel();
  326. $config_info = $config->getRegisterConfig($this->site_id, 'shop');
  327. if ($config_info[ 'data' ][ 'value' ][ 'third_party' ] && !$config_info[ 'data' ][ 'value' ][ 'bind_mobile' ]) {
  328. $data = [
  329. 'wx_openid' => $cache[ 'openid' ] ?? "",
  330. 'site_id' => $this->site_id,
  331. 'avatarUrl' => $cache[ 'headimgurl' ],
  332. 'nickName' => $cache[ 'nickname' ],
  333. 'wx_unionid' => $cache[ 'unionid' ],
  334. ];
  335. Cache::set('wechat_' . $key, null);
  336. $res = $login->authLogin($data);
  337. //生成access_token
  338. if ($res[ 'code' ] >= 0) {
  339. $token = $this->createToken($res[ 'data' ][ 'member_id' ]);
  340. // Session::set($this->params[ 'app_type' ] . "_token_" . $this->site_id, $token);
  341. // Session::set($this->params[ 'app_type' ] . "_member_id_" . $this->site_id, $res[ 'data' ][ 'member_id' ]);
  342. return $this->response($this->success([ 'token' => $token, 'can_receive_registergift' => $res[ 'data' ][ 'can_receive_registergift' ] ]));
  343. }
  344. }
  345. Cache::set('wechat_' . $key, null);
  346. return $this->response($this->success());
  347. }
  348. } elseif (time() > $cache[ 'expire_time' ]) {
  349. Cache::set('wechat_' . $key, null);
  350. return $this->response($this->error('', '已失效'));
  351. } else {
  352. return $this->response($this->error('', 'no login'));
  353. }
  354. } else {
  355. return $this->response($this->error('', '已失效'));
  356. }
  357. }
  358. }