Login.php 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2021 勾股工作室
  4. * @license https://opensource.org/licenses/Apache-2.0
  5. * @link https://www.gougucms.com
  6. */
  7. declare (strict_types = 1);
  8. namespace app\admin\controller;
  9. use app\admin\validate\UserCheck;
  10. use think\exception\ValidateException;
  11. use think\facade\Db;
  12. use think\facade\Session;
  13. class Login
  14. {
  15. //登录
  16. public function index()
  17. {
  18. return View();
  19. }
  20. private $loginAttempts = [];
  21. private $maxAttempts = 5;
  22. private $lockDuration = 600; // 10 minutes
  23. //提交登录
  24. public function login_submit()
  25. {
  26. $param = get_params();
  27. // dump($param);
  28. try {
  29. validate(UserCheck::class)->check($param);
  30. } catch (ValidateException $e) {
  31. // 验证失败 输出错误信息
  32. return to_assign(1, $e->getError());
  33. }
  34. $ip = request()->ip();
  35. if (isset($this->loginAttempts[$ip])) {
  36. if ($this->loginAttempts[$ip]['count'] >= $this->maxAttempts &&
  37. time() - $this->loginAttempts[$ip]['last_attempt'] < $this->lockDuration) {
  38. return to_assign(1, '登录尝试次数过多,请稍后再试');
  39. } elseif (time() - $this->loginAttempts[$ip]['last_attempt'] >= $this->lockDuration) {
  40. $this->loginAttempts[$ip]['count'] = 0;
  41. }
  42. }
  43. $admin = Db::name('Admin')->where(['username' => $param['username']])->find();
  44. if (empty($admin)) {
  45. $this->recordFailedAttempt($ip);
  46. return to_assign(1, '用户名或密码错误');
  47. }
  48. $param['pwd'] = set_password($param['password'], $admin['salt']);
  49. if ($admin['pwd'] !== $param['pwd']) {
  50. $this->recordFailedAttempt($ip);
  51. return to_assign(1, '用户名或密码错误');
  52. }
  53. if ($admin['status'] !== 1) {
  54. return to_assign(1, '该用户禁止登录,请于系统所有者联系');
  55. }
  56. $data = [
  57. 'last_login_time' => time(),
  58. 'last_login_ip' => request()->ip(),
  59. 'login_num' => $admin['login_num'] + 1,
  60. ];
  61. Db::name('admin')->where(['id' => $admin['id']])->update($data);
  62. $session_admin = get_config('app.session_admin'); // gougu_admin
  63. Session::set($session_admin, $admin); // null
  64. $token = make_token();
  65. set_cache($token, $admin, 7200);
  66. $admin['token'] = $token;
  67. add_log('login', $admin['id'], $data);//添加登录日志
  68. return to_assign(0, '登录成功', ['uid' => $admin['id']]);
  69. }
  70. private function recordFailedAttempt($ip) {
  71. if (!isset($this->loginAttempts[$ip])) {
  72. $this->loginAttempts[$ip] = ['count' => 0, 'last_attempt' => 0];
  73. // halt($this->loginAttempts[$ip]);
  74. }
  75. $this->loginAttempts[$ip]['count']++;
  76. $this->loginAttempts[$ip]['last_attempt'] = time();
  77. }
  78. //退出登录
  79. public function login_out()
  80. {
  81. $session_admin = get_config('app.session_admin');
  82. Session::delete($session_admin);
  83. //redirect('/')->send();
  84. return to_assign(0, "退出成功");
  85. }
  86. }