AuthController.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. <?php
  2. namespace App\Http\Controllers\V1;
  3. use App\Models\Job;
  4. use App\Models\User;
  5. use App\Services\Api\CommonService;
  6. use App\Services\Api\ErrorMsgServive;
  7. use App\Services\Api\UserService;
  8. use App\Services\JPushService;
  9. use App\Services\SmsServer;
  10. use Cache;
  11. use EasyWeChat\Factory;
  12. use Illuminate\Http\Request;
  13. use Illuminate\Support\Facades\Auth;
  14. use Illuminate\Support\Facades\DB;
  15. use Laravel\Socialite\Facades\Socialite;
  16. use Mews\Captcha\Captcha;
  17. use PHPUnit\Util\Exception;
  18. use Illuminate\Support\Facades\Validator;
  19. class AuthController extends Controller
  20. {
  21. public function __construct()
  22. {
  23. $this->wxConfig = ['app_id' => env("WECHAT_MINI_PROGRAM_APPID"), 'secret' => env("WECHAT_MINI_PROGRAM_SECRET"), 'response_type' => 'array'];
  24. }
  25. //注册
  26. public function register(Request $request)
  27. {
  28. $account = $request->input('account', '');
  29. $password = $request->input('password', '');
  30. $passwords = $request->input('passwords', '');
  31. $captcha = $request->input('captcha', '');
  32. $captcha_key = $request->input('captcha_key','');
  33. $validator = Validator::make($request->all(), [
  34. 'account' => 'required',
  35. 'name' => 'required|alpha_num',
  36. 'email' => 'required',
  37. 'password' => 'required|min:6',
  38. 'passwords' => 'required|min:6',
  39. ]);
  40. if ($validator->fails()) {
  41. return $this->error($validator->errors()->first());
  42. }
  43. if(!captcha_api_check($captcha,$captcha_key)){
  44. return $this->error("图形验证码错误!");
  45. }
  46. if($password != $passwords){
  47. return $this->error('密码不一致!');
  48. }
  49. // 查询用户是否存在
  50. $user = User::query()
  51. ->where('account','=',$account)
  52. ->orWhere('email','=',$request->email)
  53. ->first();
  54. if($user){
  55. return $this->error('账号已存在或邮箱已被注册!');
  56. }
  57. if (CommonService::is_email($request->email)){ // 邮箱格式
  58. if(!EmailController::isEmailCodeRight($request->email,$request->code)){
  59. return $this->error("验证码验证失败!");
  60. }
  61. }else{
  62. return $this->error('账号格式不正确!');
  63. }
  64. $user = \App::make('getUserInstance'); //在 app/Providers/AppServiceProvider.php 里面可以创一个单例模式
  65. $user->name = $request->name; // 姓名
  66. $user->account = $request->account; // 账号
  67. $user->email = $request->email; // 邮箱
  68. $user->password = $password; //这个不是直接存密码,User模型中使用了修改器
  69. $user->register_ip = request()->ip();
  70. $user->save();
  71. return $this->success('创建成功!');
  72. }
  73. //账号密码登录
  74. public function login(Request $request)
  75. {
  76. $account = $request->input('account');
  77. $password = $request->input('password');
  78. $jpush_reg_id = $request->input('jpush_reg_id');
  79. if (!$user = User::query()->where('account','=',$account)->first()) {
  80. return $this->error('账号不存在');
  81. }
  82. // 账号是否禁用
  83. // if($user->status == 0){
  84. // return $this->error('账号已被禁用!');
  85. // }
  86. $credentials1 = ['account' => $account, 'password' => $password];
  87. if (!auth('api')->attempt($credentials1)) {
  88. return $this->error('密码错误!');
  89. }
  90. $data = $this->doLogin($user, $jpush_reg_id);
  91. return $this->success($data);
  92. }
  93. //短信验证码登录
  94. public function loginBySmsCode(Request $request)
  95. {
  96. try {
  97. if (!$user = User::query()->where(['mobile' => $request->mobile])->first()) {
  98. return $this->error('账号不存在');
  99. }
  100. //手机验证码验证
  101. SmsServer::checkSmsCodeByVerifyKey($request->mobile, $request->smsCode);
  102. //如果登录类型和 openid 不为空
  103. $type = $request->type;
  104. if (isset($type) && !empty($type)) {
  105. if ($type == 'weixin') {
  106. if ($user->wx_openid != '') {
  107. return $this->error('已经绑定微信');
  108. }
  109. $user->wx_openid = $request->openid;
  110. $user->save();
  111. }
  112. }
  113. $data = $this->doLogin($request->mobile, $request->post('jpush_reg_id', ''));
  114. } catch (\Exception $exception) {
  115. return $this->error($exception);
  116. }
  117. return $this->success($data);
  118. }
  119. //APP第三方授权登录(微信)
  120. public function authLogin(Request $request)
  121. {
  122. try {
  123. $socialite = Socialite::driver('weixin')->stateless()->user();
  124. $user = User::query()->where('open_id', $socialite->getId())->first();
  125. if (!$user) {
  126. $data['open_id'] = $socialite->getId();
  127. $data['user'] = [];
  128. } else {
  129. $account = $user->mobile ?: $user->email;
  130. $data = $this->doLogin($account, $request->post('jpush_reg_id', ''));
  131. }
  132. } catch (Exception $exception) {
  133. ErrorMsgServive::write($exception, requst()->url());
  134. return $this->error('微信授权登录出错~');
  135. }
  136. return $this->success($data);
  137. }
  138. //微信小程序登录(微信)
  139. public function miniProgram(Request $request)
  140. {
  141. try {
  142. $mini = Factory::miniProgram($this->wxConfig);
  143. $newMini = $mini->auth->session($request->input('code'));
  144. $iv = $request->input('iv');
  145. $encryptData = $request->input('encryptData');
  146. $decryptedData = $mini->encryptor->decryptData($newMini['session_key'], $iv, $encryptData);
  147. $openId = $decryptedData['openid'];
  148. $user = User::query()->where('open_id', $openId)->first();
  149. if (!$user) {
  150. $data['open_id'] = $openId;
  151. $data['user'] = [];
  152. } else {
  153. $account = $user->mobile ?: $user->email;
  154. $data = $this->doLogin($account, $request->post('jpush_reg_id', ''));
  155. }
  156. } catch (Exception $exception) {
  157. ErrorMsgServive::write($exception, requst()->url());
  158. return $this->error('微信授权登录出错~');
  159. }
  160. return $this->success($data);
  161. }
  162. //微信小程序获取手机号
  163. public function decryptPhone(Request $request)
  164. {
  165. $user = auth('api')->user();
  166. try {
  167. $mini = Factory::miniProgram($this->wxConfig);
  168. $newMini = $mini->auth->session($request->input('code'));
  169. $iv = $request->input('iv');
  170. $encryptData = $request->input('encryptData');
  171. $decryptedData = $mini->encryptor->decryptData($newMini['session_key'], $iv, $encryptData);
  172. $user = User::query()->where('id', $user->id)->first();
  173. $user->mobile = $decryptedData['purePhoneNumber'];
  174. $user->save();
  175. } catch (\Exception $exception) {
  176. ErrorMsgServive::write($exception, requst()->url());
  177. return $this->error('获取手机号出错~');
  178. }
  179. return $this->success();
  180. }
  181. //H5 应用进行微信授权登录
  182. public function h5Oauth()
  183. {
  184. }
  185. //微信小程序 code
  186. public function miniCode()
  187. {
  188. }
  189. //执行登录
  190. public function doLogin($user, $jpush_reg_id = null)
  191. {
  192. if (!empty($jpush_reg_id)) {
  193. //清除登陆过本设备的账号设备id
  194. User::query()->where('jpush_reg_id', $jpush_reg_id)->update(['jpush_reg_id' => '']);
  195. //当前登录用户绑定设备
  196. $user->jpush_reg_id = $jpush_reg_id;
  197. //清除别名
  198. JPushService::deleteAlias('user_id_' . $user->id);
  199. //设置极光推送别名
  200. JPushService::updateAlias($user->jpush_reg_id, 'user_id_' . $user->id);
  201. }
  202. $user->online = 1;
  203. $user->last_login_time = date('Y-m-d H:i:s');
  204. $user->last_login_ip = request()->ip();
  205. if (!$user->save()) {
  206. return $this->error('登录失败!');
  207. }
  208. $token = Auth::guard('api')->fromUser($user);
  209. $userInfo = UserService::getUserInfoById($user->id);
  210. $data = [
  211. 'token' => "Bearer " . $token,
  212. 'user_info' => $userInfo,
  213. ];
  214. return $data;
  215. }
  216. //用户是否存在
  217. public function isUserExist($account)
  218. {
  219. $user = User::where(['mobile' => $account])
  220. ->orWhere(['email' => $account])
  221. ->first();
  222. if (!$user) {
  223. return false;
  224. }
  225. return $user;
  226. }
  227. //忘记密码
  228. public function forgetPassword(Request $request)
  229. {
  230. $account = $request->input('account', '');
  231. $captcha = $request->input('captcha', '');
  232. $captcha_key = $request->input('captcha_key','');
  233. $validator = Validator::make($request->all(), [
  234. 'account' => 'required',
  235. 'captcha' => 'required',
  236. 'captcha_key' => 'required',
  237. ]);
  238. if ($validator->fails()) {
  239. return $this->error($validator->errors()->first());
  240. }
  241. if(!captcha_api_check($captcha,$captcha_key)){
  242. return $this->error("图形验证码错误!");
  243. }
  244. // 查询用户是否存在
  245. $user = User::query()
  246. ->where('account','=',$account)
  247. ->first();
  248. if(!$user){
  249. return $this->error('账号不存在!');
  250. }
  251. if($user->status == 0){
  252. return $this->error('账号已被禁用!');
  253. }
  254. // 随机生成密码
  255. $password = rand(100000, 999999);
  256. $content = '您找回的密码为系统重新生成:'.$password.',登录后请自行修改!';
  257. $res = EmailController::sendNotice($user->email,'找回密码通知',$content);
  258. if(!$res){
  259. return $this->error("找回密码失败!");
  260. }
  261. $user->password = $password; // 处理过加密的
  262. $user->save();
  263. return $this->success('',0,'我们已将密码发至您的电子邮件!');
  264. }
  265. //找回ID
  266. public function findId(Request $request)
  267. {
  268. $email = $request->input('email', '');
  269. $captcha = $request->input('captcha', '');
  270. $captcha_key = $request->input('captcha_key','');
  271. $validator = Validator::make($request->all(), [
  272. 'captcha' => 'required',
  273. 'captcha_key' => 'required',
  274. 'email' => 'required',
  275. ]);
  276. if ($validator->fails()) {
  277. return $this->error($validator->errors()->first());
  278. }
  279. if(!captcha_api_check($captcha,$captcha_key)){
  280. return $this->error("图形验证码错误!");
  281. }
  282. // 查询用户是否存在
  283. $user = User::query()
  284. ->where('email','=',$email)
  285. ->first();
  286. if(!$user){
  287. return $this->error('邮箱不存在!');
  288. }
  289. if($user->status == 0){
  290. return $this->error('账号已被禁用!');
  291. }
  292. $content = '您找回的ID为:'.$user->account.',请妥善保存!';
  293. $res = EmailController::sendNotice($user->email,'找回ID通知',$content);
  294. if(!$res){
  295. return $this->error("找回ID失败!");
  296. }
  297. return $this->success('',0,'我们已将ID发至您的电子邮箱!');
  298. }
  299. //退出
  300. public function logout()
  301. {
  302. $user = auth('api')->user();
  303. if($user){
  304. if(!empty($user->jpush_reg_id)){
  305. //清空极光别名
  306. JPushService::updateAlias($user->jpush_reg_id, '');
  307. }
  308. $user->online = 0;
  309. $user->save();
  310. }
  311. auth('api')->logout();
  312. return $this->success('',0,'退出成功!');
  313. }
  314. /**
  315. * @return void
  316. * 图形验证码
  317. */
  318. public function captcha(){
  319. $captcha = app('captcha')->create('default', true);
  320. return $this->success($captcha);
  321. }
  322. }