Login.php 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. <?php
  2. /**
  3. * @Created by PhpStorm
  4. * @author: Kirin
  5. * @day: 2024/11/20
  6. * @time: 11:17
  7. */
  8. namespace app\controller\api;
  9. use app\common\ApiBaseController;
  10. use app\Request;
  11. use app\services\user\LoginServices;
  12. use app\validate\api\user\RegisterValidates;
  13. use Exception;
  14. use Psr\SimpleCache\InvalidArgumentException;
  15. use qiniu\services\CacheService;
  16. use think\db\exception\DataNotFoundException;
  17. use think\db\exception\DbException;
  18. use think\db\exception\ModelNotFoundException;
  19. use think\exception\ValidateException;
  20. use think\facade\Config;
  21. class Login extends ApiBaseController
  22. {
  23. /**
  24. * LoginController constructor.
  25. * @param Request $request
  26. * @param LoginServices $services
  27. */
  28. public function __construct(Request $request, LoginServices $services)
  29. {
  30. parent::__construct($request);
  31. $this->service = $services;
  32. }
  33. /**
  34. * H5账号登陆
  35. * @param Request $request
  36. * @return mixed
  37. * @throws DataNotFoundException|ModelNotFoundException|DbException
  38. */
  39. public function login(Request $request)
  40. {
  41. [$account, $password, $spread_uid, $login_type] = $request->postMore([
  42. 'account', 'password', 'spread_uid', ['login_type', 'account']
  43. ], true);
  44. if (!$account || !$password) {
  45. return app('json')->fail('请输入账号和密码');
  46. }
  47. if (!in_array($login_type, ['phone', 'account'])) {
  48. return $this->error('请选择登录方式');
  49. }
  50. validate(\app\validate\api\LoginValidate::class)->check(['account' => $account, 'pwd' => $password]);
  51. if ($login_type == 'phone') {
  52. if (!check_phone($account)) return app('json')->fail('请输入正确的手机号码');
  53. }
  54. return app('json')->success('登录成功', $this->service->login($account, $login_type, $password, $spread_uid));
  55. }
  56. /**
  57. * 退出登录
  58. * @param Request $request
  59. * @return mixed
  60. * @throws InvalidArgumentException
  61. */
  62. public function logout(Request $request)
  63. {
  64. $key = trim(ltrim($request->header(Config::get('cookie.token_name')), 'Bearer'));
  65. CacheService::redisHandler()->delete(md5($key));
  66. return app('json')->success('成功');
  67. }
  68. public function verifyCode()
  69. {
  70. $unique = password_hash(uniqid(true), PASSWORD_BCRYPT);
  71. CacheService::set('sms.key.' . $unique, 0, 300);
  72. $time = sys_config('verify_expire_time', 1);
  73. return app('json')->success(['key' => $unique, 'expire_time' => $time]);
  74. }
  75. public function captcha(Request $request)
  76. {
  77. ob_clean();
  78. $rep = captcha();
  79. $key = app('session')->get('captcha.key');
  80. $uni = $request->get('key');
  81. if ($uni)
  82. CacheService::set('sms.key.cap.' . $uni, $key, 300);
  83. return $rep;
  84. }
  85. /**
  86. * 验证验证码是否正确
  87. *
  88. * @param $uni
  89. * @param string $code
  90. * @return bool
  91. * @throws InvalidArgumentException
  92. */
  93. protected function checkCaptcha($uni, string $code): bool
  94. {
  95. $cacheName = 'sms.key.cap.' . $uni;
  96. if (!CacheService::has($cacheName)) {
  97. return false;
  98. }
  99. $key = CacheService::get($cacheName);
  100. $code = mb_strtolower($code, 'UTF-8');
  101. $res = password_verify($code, $key);
  102. if ($res) {
  103. CacheService::delete($cacheName);
  104. }
  105. return $res;
  106. }
  107. /**
  108. * @return mixed
  109. */
  110. public function ajcaptcha(Request $request)
  111. {
  112. $captchaType = $request->get('captchaType');
  113. return app('json')->success(aj_captcha_create((string)$captchaType));
  114. }
  115. /**
  116. * 一次验证
  117. * @return mixed
  118. */
  119. public function ajcheck(Request $request)
  120. {
  121. [$token, $pointJson, $captchaType] = $request->postMore([
  122. ['token', ''],
  123. ['pointJson', ''],
  124. ['captchaType', ''],
  125. ], true);
  126. try {
  127. aj_captcha_check_one($captchaType, $token, $pointJson);
  128. return app('json')->success();
  129. } catch (\Throwable $e) {
  130. return app('json')->fail(400336);
  131. }
  132. }
  133. /**
  134. * 验证码发送
  135. * @param Request $request
  136. * @return mixed
  137. * @throws DataNotFoundException
  138. * @throws DbException
  139. * @throws InvalidArgumentException
  140. * @throws ModelNotFoundException
  141. */
  142. public function verify(Request $request)
  143. {
  144. [$phone, $type, $key, $captchaType, $captchaVerification] = $request->postMore([
  145. ['phone', 0],
  146. ['type', ''],
  147. ['key', ''],
  148. ['captchaType', ''],
  149. ['captchaVerification', ''],
  150. ], true);
  151. $keyName = 'sms.key.' . $key;
  152. $nowKey = 'sms.' . date('YmdHi');
  153. if (!CacheService::has($keyName))
  154. return $this->error('发送验证码失败,请刷新页面重新获取');
  155. $total = 1;
  156. if (CacheService::has($nowKey)) {
  157. $total = CacheService::get($nowKey);
  158. if ($total > Config::get('sms.maxMinuteCount', 20))
  159. return app('json')->success('触发分钟级流控:' . Config::get('sms.maxMinuteCount', 20));
  160. }
  161. //二次验证
  162. try {
  163. aj_captcha_check_two($captchaType, $captchaVerification);
  164. } catch (\Throwable $e) {
  165. return app('json')->fail($e->getError());
  166. }
  167. try {
  168. validate(RegisterValidates::class)->scene('code')->check(['phone' => $phone]);
  169. } catch (ValidateException $e) {
  170. return app('json')->fail($e->getError());
  171. }
  172. $time = sys_config('verify_expire_time', 1);
  173. $smsCode = $this->service->verify($phone, $type, $time, app()->request->ip());
  174. if ($smsCode) {
  175. CacheService::set('code_' . $phone . '_' . $type, $smsCode, $time * 60);
  176. CacheService::set($nowKey, $total, 61);
  177. return app('json')->success('发送成功');
  178. } else {
  179. return app('json')->fail('发送失败');
  180. }
  181. }
  182. /**
  183. * H5注册新用户
  184. * @param Request $request
  185. * @return mixed
  186. * @throws InvalidArgumentException
  187. */
  188. public function register(Request $request)
  189. {
  190. [$phone, $captcha, $password, $nickname, $spread_uid] = $request->postMore([
  191. ['phone', ''],//手机号
  192. ['captcha', ''],//验证码
  193. ['password', ''],//密码
  194. ['nickname', ''],//密码
  195. ['spread_uid', ''],//推荐人ID
  196. ], true);
  197. try {
  198. validate(RegisterValidates::class)->scene('register')->check([
  199. 'phone' => $phone,
  200. 'captcha' => $captcha,
  201. 'password' => $password,
  202. ]);
  203. } catch (ValidateException $e) {
  204. return app('json')->fail($e->getError());
  205. }
  206. check_sms_captcha($phone, 'register', $captcha);
  207. $user_type = $request->getFromType() ? $request->getFromType() : 'h5';
  208. $registerStatus = $this->service->register($phone, $password, $spread_uid, $user_type, $nickname);
  209. if ($registerStatus) {
  210. return app('json')->success('注册成功');
  211. }
  212. return app('json')->fail('注册失败');
  213. }
  214. /**
  215. * 密码修改
  216. * @param Request $request
  217. * @return mixed
  218. * @throws DataNotFoundException
  219. * @throws DbException
  220. * @throws ModelNotFoundException
  221. */
  222. public function reset(Request $request)
  223. {
  224. [$account, $captcha, $password] = $request->postMore([['phone', ''], ['captcha', ''], ['password', '']], true);
  225. check_sms_captcha($account, 'reset', $captcha);
  226. try {
  227. validate(RegisterValidates::class)->scene('register')->check([
  228. 'phone' => $account,
  229. 'captcha' => $captcha,
  230. 'password' => $password,
  231. ]);
  232. } catch (ValidateException $e) {
  233. return app('json')->fail($e->getError());
  234. }
  235. $resetStatus = $this->service->reset($account, $password);
  236. if ($resetStatus) {
  237. return app('json')->success('修改成功');
  238. }
  239. return app('json')->fail('修改失败');
  240. }
  241. /**
  242. * 交易密码修改
  243. * @param Request $request
  244. * @return mixed
  245. * @throws DataNotFoundException
  246. * @throws DbException
  247. * @throws ModelNotFoundException
  248. */
  249. public function reset_trade_pwd(Request $request)
  250. {
  251. [$captcha, $password] = $request->postMore([['captcha', ''], ['password', '']], true);
  252. $account = $request->user()['phone'] ?? '0';
  253. check_sms_captcha($account, 'reset', $captcha);
  254. if (!check_trade_password($password))
  255. return app('json')->fail('交易密码为6位数字');
  256. $resetStatus = $this->service->trade_reset($account, $password);
  257. if ($resetStatus) {
  258. return app('json')->success('修改成功');
  259. }
  260. return app('json')->fail('修改失败');
  261. }
  262. /**
  263. * 手机号登录
  264. * @param Request $request
  265. * @return mixed
  266. * @throws Exception
  267. */
  268. public function mobile(Request $request)
  269. {
  270. [$phone, $captcha, $spread_uid] = $request->postMore([['phone', ''], ['captcha', ''], ['spread_uid', 0]], true);
  271. //验证手机号
  272. try {
  273. validate(RegisterValidates::class)->scene('code')->check(['phone' => $phone]);
  274. } catch (ValidateException $e) {
  275. return app('json')->fail($e->getError());
  276. }
  277. check_sms_captcha($phone, 'mobile', $captcha);
  278. $user_type = $request->getFromType() ? $request->getFromType() : 'h5';
  279. $token = $this->service->mobile($phone, $spread_uid, $user_type);
  280. if ($token) {
  281. return app('json')->success('登录成功', $token);
  282. } else {
  283. return app('json')->fail('登录失败');
  284. }
  285. }
  286. }