diff --git a/app/Admin/Controllers/AuthController.php b/app/Admin/Controllers/AuthController.php index 33a7b66..6243fa8 100644 --- a/app/Admin/Controllers/AuthController.php +++ b/app/Admin/Controllers/AuthController.php @@ -4,9 +4,66 @@ namespace App\Admin\Controllers; use Slowlyo\OwlAdmin\Controllers\AuthController as AdminAuthController; use Slowlyo\OwlAdmin\Admin; +use Illuminate\Http\Request; +use Illuminate\Support\Facades\Validator; +use Illuminate\Support\Facades\Hash; +use Slowlyo\OwlAdmin\Models\AdminUser; +use Symfony\Component\HttpFoundation\Response; +use App\Enums\SocialiteType; +use App\Models\UserSocialite; class AuthController extends AdminAuthController { + public function login(Request $request) + { + if (Admin::config('admin.auth.login_captcha')) { + if (!$request->has('captcha')) { + return $this->response()->fail(__('admin.required', ['attribute' => __('admin.captcha')])); + } + + if (strtolower(admin_decode($request->sys_captcha)) != strtolower($request->captcha)) { + return $this->response()->fail(__('admin.captcha_error')); + } + } + + try { + $validator = Validator::make($request->all(), [ + 'username' => 'required', + 'password' => 'required', + ], [ + 'username' . '.required' => __('admin.required', ['attribute' => __('admin.username')]), + 'password.required' => __('admin.required', ['attribute' => __('admin.password')]), + ]); + + if ($validator->fails()) { + abort(Response::HTTP_BAD_REQUEST, $validator->errors()->first()); + } + $adminModel = Admin::config("admin.auth.model", AdminUser::class); + $user = $adminModel::query()->where('username', $request->username)->first(); + if ($user && Hash::check($request->password, $user->password)) { + $module = Admin::currentModule(true); + $prefix = $module ? $module . '.' : ''; + $token = $user->createToken($prefix . 'admin')->plainTextToken; + + // 更新第三方账户 + $openid = $request->input('openid'); + $open_type = $request->input('open_type'); + if ($openid && $open_type) { + UserSocialite::where(['openid' => $openid, 'type' => SocialiteType::from($open_type)])->update([ + 'user_id' => $user->id, + 'user_type' => $user->getMorphClass(), + ]); + } + + return $this->response()->success(compact('token'), __('admin.login_successful')); + } + + abort(Response::HTTP_BAD_REQUEST, __('admin.login_failed')); + } catch (\Exception $e) { + return $this->response()->fail($e->getMessage()); + } + } + public function currentUser() { $userInfo = Admin::user()->only(['name', 'avatar', 'id']); diff --git a/app/Admin/routes.php b/app/Admin/routes.php index 44ebec7..f33be86 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -11,6 +11,7 @@ Route::group([ $router->resource('dashboard', \App\Admin\Controllers\HomeController::class); $router->get('menus', [\App\Admin\Controllers\HomeController::class, 'menus']); $router->get('current-user', [\App\Admin\Controllers\AuthController::class, 'currentUser']); + $router->post('login', [\App\Admin\Controllers\AuthController::class, 'login']); $router->get('login', [App\Admin\Controllers\AuthController::class, 'loginPage']); diff --git a/app/Enums/SocialiteType.php b/app/Enums/SocialiteType.php new file mode 100644 index 0000000..aba4033 --- /dev/null +++ b/app/Enums/SocialiteType.php @@ -0,0 +1,24 @@ +value => '微信小程序', + self::WxOfficial->value => '微信公众号', + ]; + } + + public function text() + { + return data_get(self::options(), $this->value); + } +} diff --git a/app/Http/Controllers/WechatController.php b/app/Http/Controllers/WechatController.php index 064c398..5a80908 100644 --- a/app/Http/Controllers/WechatController.php +++ b/app/Http/Controllers/WechatController.php @@ -3,12 +3,36 @@ namespace App\Http\Controllers; use Illuminate\Http\Request; +use App\Models\UserSocialite; +use App\Enums\SocialiteType; +use Slowlyo\OwlAdmin\Admin; class WechatController extends Controller { public function oauth(Request $request) { $user = session('easywechat.oauth_user.default'); - dump($user); + $openid = $user->getId(); + $socialite = UserSocialite::updateOrCreate([ + 'type' => SocialiteType::WxOfficial, + 'openid' => $openid, + ], [ + 'data' => $user, + ]); + $user = $socialite->user; + if (!$user) { + return redirect(url('/h5/pages/login/login') . '?openid=' . $openid); + } + + $module = Admin::currentModule(true); + $prefix = $module ? $module . '.' : ''; + $token = $user->createToken($prefix . 'admin')->plainTextToken; + + return redirect(url('/h5/pages/index/welcome') . '?token=' . $token); + } + + protected function response() + { + return Admin::response(); } } diff --git a/app/Http/Middleware/UserSocialite.php b/app/Http/Middleware/UserSocialite.php new file mode 100644 index 0000000..cb88d9c --- /dev/null +++ b/app/Http/Middleware/UserSocialite.php @@ -0,0 +1,33 @@ + 'omDRm6ial5hRdys0NpnHQpYJ44aY', + 'name' => '潘亮', + 'nickname' => '潘亮', + 'avatar' => 'https://via.placeholder.com/64x64.png', + 'email' => null, + 'original' => [], + 'provider' => 'WeChat', + ]); + session(['easywechat.oauth_user.default' => $user]); + } + return $next($request); + } +} diff --git a/app/Models/UserSocialite.php b/app/Models/UserSocialite.php new file mode 100644 index 0000000..7985651 --- /dev/null +++ b/app/Models/UserSocialite.php @@ -0,0 +1,24 @@ + SocialiteType::class, + 'data' => 'json' + ]; + + public function user() + { + return $this->morphTo(__FUNCTION__, 'user_type', 'user_id'); + } +} diff --git a/database/migrations/2023_09_21_180557_create_user_socialites_table.php b/database/migrations/2023_09_21_180557_create_user_socialites_table.php new file mode 100644 index 0000000..49f73b2 --- /dev/null +++ b/database/migrations/2023_09_21_180557_create_user_socialites_table.php @@ -0,0 +1,31 @@ +id(); + $table->string('type'); + $table->nullableMorphs('user'); + $table->string('openid'); + $table->json('data'); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('user_socialites'); + } +}; diff --git a/public/h5/index.html b/public/h5/index.html index 09d7fae..23a2706 100644 --- a/public/h5/index.html +++ b/public/h5/index.html @@ -1,2 +1,2 @@