model = new Admin; } /** * 账户设置 * @return Response * @throws Throwable */ public function index() { return raw_view('account/index'); } /** * 登录 * @param Request $request * @return Response * @throws BusinessException */ public function login(Request $request): Response { $this->checkDatabaseAvailable(); $captcha = $request->post('captcha', ''); if (strtolower($captcha) !== session('captcha-login')) { return $this->json(1, '验证码错误'); } $request->session()->forget('captcha-login'); $username = $request->post('username', ''); $password = $request->post('password', ''); if (!$username) { return $this->json(1, '用户名不能为空'); } $this->checkLoginLimit($username); $admin = Admin::where('username', $username)->first(); if (!$admin || !Util::passwordVerify($password, $admin->password)) { return $this->json(1, '账户不存在或密码错误'); } if ($admin->status != 0) { return $this->json(1, '当前账户暂时无法登录'); } $admin->login_at = date('Y-m-d H:i:s'); $admin->save(); $this->removeLoginLimit($username); $admin = $admin->toArray(); $session = $request->session(); $admin['password'] = md5($admin['password']); $session->set('admin', $admin); return $this->json(0, '登录成功', [ 'nickname' => $admin['nickname'], 'token' => $request->sessionId(), ]); } /** * 退出 * @param Request $request * @return Response */ public function logout(Request $request): Response { $request->session()->delete('admin'); return $this->json(0); } /** * 获取登录信息 * @param Request $request * @return Response */ public function info(Request $request): Response { $admin = admin(); if (!$admin) { return $this->json(1); } $info = [ 'id' => $admin['id'], 'username' => $admin['username'], 'nickname' => $admin['nickname'], 'avatar' => $admin['avatar'], 'email' => $admin['email'], 'mobile' => $admin['mobile'], 'isSuperAdmin' => Auth::isSuperAdmin(), 'token' => $request->sessionId(), ]; return $this->json(0, 'ok', $info); } /** * 更新 * @param Request $request * @return Response */ public function update(Request $request): Response { $allow_column = [ 'nickname' => 'nickname', 'avatar' => 'avatar', 'email' => 'email', 'mobile' => 'mobile', ]; $data = $request->post(); $update_data = []; foreach ($allow_column as $key => $column) { if (isset($data[$key])) { $update_data[$column] = $data[$key]; } } if (isset($update_data['password'])) { $update_data['password'] = Util::passwordHash($update_data['password']); } Admin::where('id', admin_id())->update($update_data); $admin = admin(); unset($update_data['password']); foreach ($update_data as $key => $value) { $admin[$key] = $value; } $request->session()->set('admin', $admin); return $this->json(0); } /** * 修改密码 * @param Request $request * @return Response */ public function password(Request $request): Response { $hash = Admin::find(admin_id())['password']; $password = $request->post('password'); if (!$password) { return $this->json(2, '密码不能为空'); } if ($request->post('password_confirm') !== $password) { return $this->json(3, '两次密码输入不一致'); } if (!Util::passwordVerify($request->post('old_password'), $hash)) { return $this->json(1, '原始密码不正确'); } $update_data = [ 'password' => Util::passwordHash($password) ]; Admin::where('id', admin_id())->update($update_data); return $this->json(0); } /** * 验证码 * @param Request $request * @param string $type * @return Response */ public function captcha(Request $request, string $type = 'login'): Response { $builder = new PhraseBuilder(4, 'abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ'); $captcha = new CaptchaBuilder(null, $builder); $captcha->build(120); $request->session()->set("captcha-$type", strtolower($captcha->getPhrase())); $img_content = $captcha->get(); return response($img_content, 200, ['Content-Type' => 'image/jpeg']); } /** * 检查登录频率限制 * @param $username * @return void * @throws BusinessException */ protected function checkLoginLimit($username) { $limit_log_path = runtime_path() . '/login'; if (!is_dir($limit_log_path)) { mkdir($limit_log_path, 0777, true); } $limit_file = $limit_log_path . '/' . md5($username) . '.limit'; $time = date('YmdH') . ceil(date('i')/5); $limit_info = []; if (is_file($limit_file)) { $json_str = file_get_contents($limit_file); $limit_info = json_decode($json_str, true); } if (!$limit_info || $limit_info['time'] != $time) { $limit_info = [ 'username' => $username, 'count' => 0, 'time' => $time ]; } $limit_info['count']++; file_put_contents($limit_file, json_encode($limit_info)); if ($limit_info['count'] >= 5) { throw new BusinessException('登录失败次数过多,请5分钟后再试'); } } /** * 解除登录频率限制 * @param $username * @return void */ protected function removeLoginLimit($username) { $limit_log_path = runtime_path() . '/login'; $limit_file = $limit_log_path . '/' . md5($username) . '.limit'; if (is_file($limit_file)) { unlink($limit_file); } } protected function checkDatabaseAvailable() { if (!config('plugin.admin.database')) { throw new BusinessException('请重启webman'); } } }