AuthController.php 15 KB

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