登陸功能是項目中最基本的功能,說簡單也簡單,可是也不是那麼簡單,還是架構問題吧!
登陸是一個項目的入口,是基礎,我們應該怎麼架構這個問題,下面看看我的方法:
1.毫無疑問,是我們的登陸的控制器
public function doLogin() {
// 驗證令牌
$this->checkFormToken();
// 密碼登錄
/** @var AuthService $auth_service */
$auth_service = D('Auth', 'Service');
list($code, $message, $manager) = $auth_service->doLoginPassword(I('username'), I('password'));
if ( $code < 0 ) {
return $this->ajaxResponseToken($code, $message);
}
$manager_model = D('Manager');
$info = array('last_login_ip' => get_client_ip(), 'last_login_time' => datetime(), 'relogin' => 0);
$manager_model->updateManagerById($manager['manager_id'], $info);
// 設置會話數據
session('manager', $manager);
session('manager_id', $manager['manager_id']);
session('menu_list', NULL);
$this->ajaxResponse(0, '登錄成功!');
}
2.涉及到我們登陸的服務層
public function doLoginPassword($username, $password) {
if ( empty($username) ) {
return array(-1, '請輸入賬號!', []);
}
if ( empty($password) ) {
return array(-2, '密碼不能爲空!', []);
}
$login_log_model = D('LoginLog');
$fail_count = $login_log_model->getLoginFailNum($username, day());
if ( $fail_count >= C('MAX_LOGIN_FAIL_NUMBER') ) {
return array(-1, "您今日已經達到錯誤登陸的次數上限,每天最多 ".C('MAX_LOGIN_FAIL_NUMBER')." 次", []);
}
$manager_model = D('Manager');
$manager = $manager_model->getManagerByUsername($username);
if ( empty($manager) ) {
return array(-1, '賬號不存在!', []);
}
$log = array('username' => $username, 'password' => $password, 'ip' => get_client_ip(),
'ctime' => datetime());
if ( !password_verify($password, $manager['password']) ) {
$log['result'] = 'fail';
$log['message'] = '密碼不正確';
$login_log_model->addManagerLoginLog($log); // 添加登錄日誌
// TODO 用戶當日輸入密碼錯誤超過一定次數則凍結賬號
return array(-2, $log['message'], []);
}
// IP地址檢查
if ( !empty($manager['allow_ip'])
&& !$this->isIpAllow(get_client_ip(), $manager['allow_ip']) ) {
$log['result'] = 'fail';
$log['message'] = 'IP地址被限制登錄';
$login_log_model->addManagerLoginLog($log);
return array(-1, $log['message'], []);
}
// 添加登錄日誌
$log['result'] = 'success';
$log['message'] = '登錄成功';
$login_log_model->addManagerLoginLog($log);
// 賬號未激活算登錄成功
if ( $manager['active'] != 'Y' ) {
return array(-1, '賬號未激活!', []);
}
return array(0, '登錄成功!', $manager);
}
3.在服務層我們還需要一個功能就是確定當前用戶的錯誤登陸次數,(這個我是在model控制)
public function getLoginFailNum($username, $day = NULL) {
if ( empty($day) ) $day = day();
return $this->__log_model->field("id")
->where("username='%s' AND result='fail' AND ctime >= '%s' AND ctime <= '%s'", $username, $day.' 00:00:00', $day.' 23:59:59')
->count();
}