AuthController.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. <?php
  2. namespace App\Http\Controllers\V1;
  3. use App\libs\helpers\Response;
  4. use App\libs\wechat\auth\WeChat;
  5. use App\Models\Config;
  6. use App\Models\Share;
  7. use App\Models\User;
  8. use App\Services\Api\ErrorMsgServive;
  9. use App\Services\Api\UserService;
  10. use App\Services\JPushService;
  11. use App\Services\SmsServer;
  12. use EasyWeChat\Factory;
  13. use Illuminate\Http\JsonResponse;
  14. use Illuminate\Http\Request;
  15. use Illuminate\Support\Facades\Auth;
  16. use Laravel\Socialite\Facades\Socialite;
  17. use PHPUnit\Util\Exception;
  18. class AuthController extends Controller
  19. {
  20. public function __construct()
  21. {
  22. $this->wxConfig = [
  23. 'app_id' => env('WECHAT_MINI_PROGRAM_APPID'),
  24. 'secret' => env('WECHAT_MINI_PROGRAM_SECRET'),
  25. 'response_type' => 'array',
  26. ];
  27. }
  28. // 注册
  29. public function register(Request $request)
  30. {
  31. $mobile = $request->input('mobile', '');
  32. $password = $request->input('password', '');
  33. $validator = \Validator::make($request->all(), [
  34. 'mobile' => 'required',
  35. 'password' => 'required|min:6',
  36. ]);
  37. if ($validator->fails()) {
  38. return $this->error($validator->errors()->first());
  39. }
  40. if (UserService::checkUserByMobile($mobile)) {
  41. return $this->error('手机号已被占用');
  42. }
  43. try { // 手机验证码验证
  44. SmsServer::checkSmsCodeByVerifyKey($request->verifyKey, $request->code);
  45. } catch (Exception $exception) {
  46. return $this->error($exception->getMessage());
  47. }
  48. $user = App::make('getUserInstance'); // 在 app/Providers/AppServiceProvider.php 里面可以创一个单例模式
  49. $user->name = 'User' . mb_substr($mobile, 0, 6);
  50. $user->avatar = '';
  51. $user->mobile = $mobile;
  52. $user->password = $password; // 这个不是直接存密码,User模型中使用了修改器
  53. $user->register_ip = request()->ip();
  54. return $this->success('创建成功!');
  55. }
  56. // 账号密码登录
  57. public function login(Request $request)
  58. {
  59. $account = $request->input('account');
  60. $password = $request->input('password');
  61. $jpush_reg_id = $request->input('jpush_reg_id');
  62. if (!$user = User::query()->where(['mobile' => $account])->orWhere(['email' => $account])->first()) {
  63. return $this->error('账号不存在');
  64. }
  65. $credentials1 = ['mobile' => $account, 'password' => $password];
  66. $credentials2 = ['email' => $account, 'password' => $password];
  67. if (!auth('api')->attempt($credentials1) && !auth('api')->attempt($credentials2)) {
  68. return $this->error('密码错误!');
  69. }
  70. $data = $this->doLogin($user, $jpush_reg_id);
  71. return $this->success($data);
  72. }
  73. // APP第三方授权登录(微信)
  74. public function authLogin(Request $request)
  75. {
  76. try {
  77. $socialite = Socialite::driver('weixin')->stateless()->user();
  78. $user = User::query()->where('open_id', $socialite->getId())->first();
  79. if (!$user) {
  80. $data['open_id'] = $socialite->getId();
  81. $data['user'] = [];
  82. } else {
  83. $account = $user->mobile ?: $user->email;
  84. $data = $this->doLogin($account, $request->post('jpush_reg_id', ''));
  85. }
  86. } catch (Exception $exception) {
  87. ErrorMsgServive::write($exception, requst()->url());
  88. return $this->error('微信授权登录出错~');
  89. }
  90. return $this->success($data);
  91. }
  92. // 微信小程序登录(微信)
  93. public function miniProgram(Request $request)
  94. {
  95. try {
  96. $helpId = $request->input('helpId', 0);
  97. $info = WeChat::mini()->code2Openid($request->input('code'));
  98. $openId = $info['openid'];
  99. // $openId = 'ocU_x5RN8huhJSIVtn9X3TQ8Zq4s1';
  100. $user = User::query()->where('open_id', $openId)->first();
  101. if (!$user) {
  102. $data['open_id'] = $openId;
  103. $data['user'] = [];
  104. $user = User::query()->create([
  105. 'open_id' => $openId,
  106. 'online' => 1,
  107. 'last_login_time' => date('Y-m-d H:i:s'),
  108. 'last_login_ip' => request()->ip(),
  109. 'sessionKey' => $info['session_key'] ?? '',
  110. 'share_pid' => $helpId,
  111. 'share_date' => date('Y-m-d H:i:s'),
  112. ]);
  113. $user = User::query()->find($user->id);
  114. if ($helpId > 0 && $helpId != $user->id) {
  115. $helpUserData = User::query()->find($helpId);
  116. if (!$helpUserData->is_share) {
  117. $this->diamond($helpId, $user->id);
  118. }
  119. }
  120. } else {
  121. $user->online = 1;
  122. $user->last_login_time = date('Y-m-d H:i:s');
  123. $user->last_login_ip = request()->ip();
  124. $user->sessionKey = $info['session_key'] ?? '';
  125. if (!$user->save()) {
  126. return $this->error('数据保存失败');
  127. }
  128. }
  129. $token = Auth::guard('api')->fromUser($user);
  130. $userInfo = UserService::getUserInfoById($user->id);
  131. $data = [
  132. 'token' => 'Bearer ' . $token,
  133. 'user_info' => $userInfo,
  134. ];
  135. return Response::success($data);
  136. } catch (Exception $exception) {
  137. ErrorMsgServive::write($exception, requst()->url());
  138. return $this->error('微信授权登录出错~');
  139. }
  140. return $this->success($data);
  141. }
  142. private function extend($helpId = 0)
  143. {
  144. }
  145. /**
  146. * 通过邀请获得钻石.
  147. *
  148. * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model
  149. */
  150. private function diamond($helpId = 0, $pid = 0)
  151. {
  152. (int) $diamond = Config::query()->where('key', 'help_diamond')->value('value');
  153. $invite = User::query()->where('share_pid', $helpId)->count();
  154. if ($invite == $diamond) {
  155. $share = Share::query()->create([
  156. 'user_id' => $helpId,
  157. 'pid' => $pid,
  158. 'diamond' => $diamond,
  159. 'desc' => '通过邀请' . $diamondCount . '人获得' . $diamond . '次数',
  160. ]);
  161. User::query()->where('id', $helpId)->increment('diamond', $diamond);
  162. }
  163. return $share ?? [];
  164. }
  165. // 微信小程序获取手机号
  166. public function decryptPhone(Request $request)
  167. {
  168. $user = auth('api')->user();
  169. try {
  170. $mini = Factory::miniProgram($this->wxConfig);
  171. $newMini = $mini->auth->session($request->input('code'));
  172. $iv = $request->input('iv');
  173. $encryptData = $request->input('encryptData');
  174. $decryptedData = $mini->encryptor->decryptData($newMini['session_key'], $iv, $encryptData);
  175. $user = User::query()->where('id', $user->id)->first();
  176. $user->mobile = $decryptedData['purePhoneNumber'];
  177. $user->save();
  178. } catch (\Exception $exception) {
  179. ErrorMsgServive::write($exception, requst()->url());
  180. return $this->error('获取手机号出错~');
  181. }
  182. return $this->success();
  183. }
  184. // H5 应用进行微信授权登录
  185. public function h5Oauth()
  186. {
  187. }
  188. // 微信小程序 code
  189. public function miniCode()
  190. {
  191. }
  192. public function wechat(Request $request): JsonResponse
  193. {
  194. try {
  195. $code = $request->input('code');
  196. $app = $this->getUniFactory(3)->mini();
  197. $res = $app->auth->session($code);
  198. return $this->doLogin($res['openid'], '', 3, $res['session_key']);
  199. } catch (\Exception $e) {
  200. ErrorMsgServive::write($e, \request()->url());
  201. return $this->error('微信授权登陆出错');
  202. }
  203. }
  204. // 字节跳动登陆 code
  205. public function bytedance(Request $request): JsonResponse
  206. {
  207. try {
  208. $code = $request->input('code');
  209. $app = $this->getUniFactory();
  210. $res = $app->login($code);
  211. return $this->doLogin($res['openid'], $res['unionid'], 1, $res['session_key']);
  212. } catch (\Exception $e) {
  213. ErrorMsgServive::write($e, \request()->url());
  214. return $this->error('字节授权登陆出错');
  215. }
  216. }
  217. // 快手登陆 code
  218. public function kuaishou(Request $request): JsonResponse
  219. {
  220. try {
  221. $code = $request->input('code');
  222. $app = $this->getUniFactory(2);
  223. $res = $app->login($code);
  224. return $this->doLogin($res['open_id'], '', 2, $res['session_key']);
  225. } catch (\Exception $e) {
  226. ErrorMsgServive::write($e, \request()->url());
  227. return $this->error('快手授权登陆出错');
  228. }
  229. }
  230. /**
  231. * 执行登录.
  232. *
  233. * @return JsonResponse
  234. */
  235. private function doLogin($openid, $sessionKey)
  236. {
  237. $user = User::where('open_id', $openid)->first();
  238. if (!$user) {
  239. $user = new User();
  240. $user->open_id = $openid;
  241. $user->sessionKey = $sessionKey;
  242. $user->save();
  243. $user = User::where('id', $user->id)->first();
  244. } else {
  245. $user->sessionKey = $sessionKey;
  246. $user->last_login_ip = \request()->ip();
  247. $user->last_login_time = time();
  248. $user->save();
  249. }
  250. $token = Auth::guard('api')->fromUser($user);
  251. $user = User::query()->where('id', $user->id)->first();
  252. return $this->success([
  253. 'token' => 'Bearer ' . $token,
  254. 'user_info' => $user,
  255. ]);
  256. }
  257. // 执行登录
  258. public function doLogin1($user, $jpush_reg_id = null)
  259. {
  260. $user->online = 1;
  261. $user->last_login_time = date('Y-m-d H:i:s');
  262. $user->last_login_ip = request()->ip();
  263. if (!$user->save()) {
  264. return $this->error('数据保存失败');
  265. }
  266. $token = Auth::guard('api')->fromUser($user);
  267. $userInfo = UserService::getUserInfoById($user->id);
  268. $data = [
  269. 'token' => 'Bearer ' . $token,
  270. 'user_info' => $userInfo,
  271. ];
  272. return $data;
  273. }
  274. // 用户是否存在
  275. public function isUserExist($account)
  276. {
  277. $user = User::where(['mobile' => $account])
  278. ->orWhere(['email' => $account])
  279. ->first();
  280. if (!$user) {
  281. return false;
  282. }
  283. return $user;
  284. }
  285. // 忘记密码
  286. public function forgetPassword(Request $request)
  287. {
  288. if ($request->new_password != $request->confirm_password) {
  289. return $this->error('两次密码不一致');
  290. }
  291. try {
  292. SmsServer::checkSmsCodeByVerifyKey($request->verifyKey, $request->code);
  293. } catch (Exception $exception) {
  294. return $this->error($exception->getMessage());
  295. }
  296. $user->password = $request->new_password;
  297. $user->save();
  298. return $this->success();
  299. }
  300. // 退出
  301. public function logout()
  302. {
  303. $user = auth('api')->user();
  304. // 清空极光别名
  305. JPushService::updateAlias($user->jpush_reg_id, '');
  306. $user->online = 0;
  307. $user->save();
  308. auth('api')->logout();
  309. return $this->success();
  310. }
  311. }