AuthController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. <?php
  2. /*
  3. * This file is part of the Jiannei/lumen-api-starter.
  4. *
  5. * (c) Jiannei <longjian.huang@foxmail.com>
  6. *
  7. * This source file is subject to the MIT license that is bundled
  8. * with this source code in the file LICENSE.
  9. */
  10. namespace App\Http\Controllers\Api\Base;
  11. use App\Http\Controllers\Controller;
  12. use App\Http\Middleware\SingleLoginLimit;
  13. use App\Repositories\Enums\ModelStatusEnum;
  14. use App\Repositories\Enums\ResponseCodeEnum;
  15. use App\Repositories\Models\Base\User;
  16. use App\Repositories\Transformers\Base\UserTransformer;
  17. use App\Support\Traits\LoginLimit;
  18. use Carbon\Carbon;
  19. use Illuminate\Http\Request;
  20. use Illuminate\Support\Facades\Cache;
  21. use Illuminate\Support\Facades\Hash;
  22. use Jiannei\Response\Laravel\Support\Facades\Response;
  23. class AuthController extends Controller
  24. {
  25. use LoginLimit;
  26. /**
  27. * Create a new controller instance.
  28. */
  29. public function __construct()
  30. {
  31. // $this->middleware('throttle:10,1', ['only' => ['login', 'me']]);
  32. }
  33. /**
  34. * 登录
  35. * Author: Mead
  36. */
  37. public function login(Request $request)
  38. {
  39. $this->validate($request, [
  40. 'username' => 'required',
  41. 'password' => 'required|min:6'
  42. ]);
  43. $credentials = request(['username', 'password']);
  44. $credentials['password'] = base64_decode($credentials['password']);
  45. $credentials['status'] = ModelStatusEnum::OK;
  46. $username = $credentials['username'];
  47. $msg = $this->isCanLogin($request, $username, 'api');
  48. if ($msg) {
  49. return Response::fail($msg, ResponseCodeEnum::SERVICE_LOGIN_ERROR);
  50. }
  51. if (!$token = auth()->guard('api')->attempt($credentials)) {
  52. $this->storeLoginLog($request, $username, 'api');
  53. return Response::fail('账号或密码不对!', ResponseCodeEnum::SERVICE_LOGIN_ERROR);
  54. }
  55. $user = auth('api')->user();
  56. $this->clearLoginLogs($request, $username, 'api');
  57. SingleLoginLimit::setToken('api', $user->id, $token);
  58. $user = (new UserTransformer())->transform($user);
  59. $permissions = login_user()->getAllPermissions()->pluck('name');
  60. return Response::success(compact('token', 'user', 'permissions'));
  61. }
  62. /**
  63. * 退出
  64. * @return mixed
  65. * Author: Mead
  66. */
  67. public function logout()
  68. {
  69. auth('api')->logout();
  70. return Response::noContent();
  71. }
  72. /**
  73. * 注册
  74. * Author: Mead
  75. */
  76. public function store(Request $request)
  77. {
  78. $this->validate($request, [
  79. 'name' => 'required',
  80. // 'turename' => 'required',
  81. 'mobile' => 'required',
  82. 'username' => 'required|min:8|unique:base_users,username',
  83. 'password' => 'required|min:6'
  84. ]);
  85. $data = $request->only(['turename', 'mobile', 'username', 'password']);
  86. $data['password'] = Hash::make($data['password']);
  87. User::query()->create($data);
  88. return Response::success(null);
  89. }
  90. /**
  91. * 用户
  92. * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Resources\Json\JsonResource
  93. * Author: Mead
  94. */
  95. public function me()
  96. {
  97. $me = (new UserTransformer())->transform(User::query()->find(login_user_id()));
  98. return Response::success($me);
  99. }
  100. /**
  101. * 修改个人信息
  102. * @param Request $request
  103. * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Resources\Json\Resource
  104. * @throws \Illuminate\Validation\ValidationException
  105. * Author: Mead
  106. */
  107. public function update(Request $request)
  108. {
  109. $this->validate($request, [
  110. 'name' => 'required',
  111. 'headimg' => 'sometimes',
  112. 'sex' => 'nullable',
  113. 'email' => 'nullable|email',
  114. 'class' => 'nullable',
  115. 'mobile' => 'nullable|mobile',
  116. 'intro' => 'nullable',
  117. 'personal_signature' => 'nullable',
  118. 'userrate' => 'nullable',
  119. ]);
  120. try {
  121. $data = $request->only(['turename', 'headimg', 'email', 'mobile', 'class', 'intro', 'personal_signature', 'userrate', 'name', 'sex']);
  122. $re = User::query()->where('id', login_user_id())->update($data);
  123. if ($re) {
  124. return Response::success(null);
  125. }
  126. return $this->errorFail();
  127. } catch (\Exception $e) {
  128. $this->errorStore($e);
  129. }
  130. }
  131. /**
  132. * 修改密码
  133. * @param Request $request
  134. * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Resources\Json\Resource
  135. * @throws \Illuminate\Validation\ValidationException
  136. * Author: Mead
  137. */
  138. public function changePassword(Request $request)
  139. {
  140. $this->validate($request, [
  141. 'password' => 'required|min:6|confirmed',
  142. ]);
  143. $password = $request->get('password');
  144. $data['password'] = Hash::make($password);
  145. $re = User::query()->where('id', login_user_id())->update($data);
  146. if ($re) {
  147. return Response::success(null);
  148. }
  149. return $this->errorFail();
  150. }
  151. /**
  152. * 手机验证码
  153. * @param Request $request
  154. * Author: Mead
  155. */
  156. public function verificationCode(Request $request)
  157. {
  158. $this->validate($request, [
  159. 'mobile' => 'required|mobile',
  160. ]);
  161. $mobile = $request->get('mobile');
  162. $code = rand(1000, 9999);
  163. // try {
  164. // app('easy_sms')->send($mobile, [
  165. // 'template' => config('sms.template.verification_code'),
  166. // 'data' => [
  167. // 'code' => $code
  168. // ]
  169. // ]);
  170. //
  171. // } catch (\Exception $exception) {
  172. // Log::error($exception);
  173. // return Response::fail('发送失败');
  174. // }
  175. Cache::put("verification_code_{$mobile}", $code, Carbon::now()->addMinutes(5));
  176. return Response::success($code);
  177. }
  178. /**
  179. * 手机号登录
  180. * @param Request $request
  181. * Author: Mead
  182. */
  183. public function mobileLogin(Request $request)
  184. {
  185. $this->validate($request, [
  186. 'mobile' => 'required|mobile',
  187. 'code' => 'required|size:4',
  188. ]);
  189. $mobile = $request->get('mobile');
  190. $code = $request->get('code');
  191. // $cache_code = Cache::get("verification_code_{$mobile}", false);
  192. //
  193. // if ((int)$cache_code !== (int)$code) {
  194. // return Response::fail('验证码错误');
  195. // }
  196. $user = User::query()->where('mobile', $mobile)->with('organization')->select(['id', 'name', 'mobile', 'headimg', 'sex', 'organization_id', 'status'])->where('status', ModelStatusEnum::OK)->orderByDesc('id')->first();
  197. if (!$user) {
  198. return Response::fail('找不到该用户');
  199. // $user = User::query()->create([
  200. // 'name' => '圆圈导航-' . rand(99999, 10000),
  201. // 'mobile' => $mobile,
  202. // ]);
  203. }
  204. $token = auth('api')->login($user);
  205. $user = (new UserTransformer())->transform($user);
  206. $permissions = login_user()->getAllPermissions()->pluck('name');
  207. return Response::success(compact('token', 'user', 'permissions'));
  208. }
  209. /**
  210. * 小程序登录
  211. * Author: Mead
  212. */
  213. public function weappLogin(Request $request)
  214. {
  215. $this->validate($request, [
  216. 'appid' => 'required',
  217. 'code' => 'required',
  218. ]);
  219. $code = $request->code;
  220. $appid = $request->appid;
  221. if ($appid !== config('wechat.mini_program.default.app_id')) {
  222. return $this->error('app_id is error');
  223. }
  224. $response = [];
  225. try {
  226. // $miniProgram = Factory::miniProgram(config('wechat'));
  227. $miniProgram = app('wechat.mini_program');
  228. $data = $miniProgram->auth->session($code);
  229. } catch (\Exception $exception) {
  230. return $this->error('code 不正确,请刷新重试');
  231. }
  232. if (isset($data['errcode'])) {
  233. return $this->error('code 不正确,请刷新重试');
  234. }
  235. $user = User::query()->where('credential', $data['openid'])->first();
  236. //response参数
  237. $response['session_key'] = $data['session_key'];
  238. $is_new_user = false;
  239. if (!$user) {
  240. //注册用户
  241. $userInfo['name'] = config('site.userName', '用户') . '-' . rand(10000, 99999);
  242. $userInfo['credential'] = $data['openid'];
  243. $user = User::query()->create($userInfo);
  244. $is_new_user = true;
  245. }
  246. $token = auth('api')->login($user);
  247. $response['token'] = 'Bearer ' . $token;
  248. $response['exp'] = Carbon::now()->getTimestamp();
  249. $response['user'] = $user;
  250. $response['is_new_user'] = $is_new_user;
  251. $permissions = login_user()->getAllPermissions()->pluck('name');
  252. $response['permissions'] = $permissions;
  253. return Response::success($response);
  254. }
  255. /**
  256. * 更新用户基本信息
  257. * User: Mead
  258. */
  259. public function weappUserInfoSync(Request $request)
  260. {
  261. $this->validate($request, [
  262. 'nickName' => 'required',
  263. 'gender' => 'required',
  264. ]);
  265. try {
  266. $user = auth('api')->user();
  267. User::query()->where('id', $user->id)->update([
  268. 'name' => $request->get('nickName', $user->nickname),
  269. 'sex' => $request->get('gender', 0),
  270. // 'country' => $request->get('country', 'China'),
  271. // 'province' => $request->get('province', 'Henan'),
  272. // 'city' => $request->get('city', 'Zhengzhou'),
  273. 'headimg' => $request->get('avatarUrl', config('filesystems.disks.qiniu.url') . '/logo.png') ?? config('filesystems.disks.qiniu.url') . "/logo.png",
  274. // 'language' => $request->get('language', 'zh_CN'),
  275. 'is_sync_info' => 1
  276. ]);
  277. $me = (new UserTransformer())->transform(User::query()->where('id', $user->id)->first());
  278. return Response::success($me);
  279. } catch (\Exception $exception) {
  280. return $this->error($exception);
  281. }
  282. }
  283. /**
  284. * 微信小程序绑定用户手机号
  285. * @param Request $request
  286. * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\Resources\Json\Resource|void
  287. * Author: Mead
  288. */
  289. public function weappBindMobile(Request $request)
  290. {
  291. $this->validate($request, [
  292. 'session_key' => 'required',
  293. 'iv' => 'required',
  294. 'encryptedData' => 'required',
  295. ]);
  296. try {
  297. //微信解析手机号
  298. $session = $request->get('session_key');
  299. $iv = $request->get('iv');
  300. $encryptedData = $request->get('encryptedData');
  301. if (!$iv) {
  302. return $this->error('授权失败');
  303. }
  304. $miniProgram = app('wechat.mini_program');
  305. $decryptedData = $miniProgram->encryptor->decryptData($session, $iv, $encryptedData);
  306. $mobile = $decryptedData['purePhoneNumber'];
  307. User::query()->where('id', login_user_id())->update([
  308. 'mobile' => $mobile,
  309. 'is_bind_mobile' => 1
  310. ]);
  311. return Response::success(null);
  312. } catch (\Exception $exception) {
  313. return $this->exception($exception);
  314. }
  315. }
  316. }