ShopCMS 开发文档
HFramework 开发文档

7.4 用户验证与授权

会员体系是一般网站都具有的功能,本框架提供了用户类(位于:application/extension/HUser.php),内有会员登录、退出、状态信息保持的功能的方法。以此用户类为基础,结合您自己的业务逻辑,很容易开发出个性化的授权与验证功能。
用户的验证与授权的相关功能,下面用具体的实例讲解:

1,登录当前用户,也就是把当前用户的用户状态设为已登录,一般用于验证完用户名密码之后:
<?php
H::user()->login($timeout);//$timeout int 型,是设置超时时间,单位为秒,可以不填,默认为0表示会话状态随浏览器关闭而终止
?>


2,为登录用户设置状态信息,方便其他场景获取:
<?php
H::user()->set('id', $userId);//用户状态中设置用户ID
H::user()->set('username', $username);//用户状态中设置用户名
H::user()->set('routes', $routes);//用户状态中设置当前用户可访问的路由,用于用户授权
?>


3. 获取用户信息,在任何地方均可调用,如果 获取不到则返回 null
<?php
$userId = H::user()->get('id');//获取上面设置的用户名,等价于:H::user('id');
$username = H::user()->get('username');//获取上面设置的用户名,等价于:H::user('username');
$routes = H::user()->get('routes');//获取上面设置的用户名,等价于:H::user('routes');

//框架为获取用户ID也提供了一个专用的方法
$userId = H::user()->getId();//此方法如果没有获取到ID,则返回int 0
?>


4. 判断用户是否登录
<?php
$isLogin = H::user()->isLogin();//返回true表示用户已登录,否则用户未登录
?>


5. 注销用户的登录状态,常用于用户退出的操作
<?php
$isLogin = H::user()->logout();//返回true表示成功退出
?>
注意: 此方法会删除通过 H::user()->set($key, $value) 创建的SESSION信息
但不会删除 H::session[$key] = $str 创建的SESSION信息


6. 强制跳转到登录页
<?php
//参数可设为 true 或者 false,如果为true,会立即跳转,此语句后面的代码将不被执行
//如果为false,此方法会返回登录页的网址,语句后面的代码会继续执行
H::user()->goLogin(false);
?>
注意:
此方法在跳转或者返回时,会自动带上当前请求的网址,以 ?的形式传递参数
此方法依赖主配置文件总 login_url 的配置,如果未配置,会抛出错误。


7,用户登录与授权的示例,示例中应用了安全类、验证类和路由限制的方法,这些类和方法将在下面的专题中继续剖析:
<?php
/**
	* 管理员登录
	 * @param $username string 用户名
	 * @param $password string 密码
	 * @param $imgcode  string 图像验证码
	 * @param $timeout int  保存时间 秒    默认为0,即回话时间
	 * @return boolen 是否登录成功
	 */
	public function login($username, $password, $imgCode, $timeout=0){
		//验证数据
		$rules = array(
			array('username,password', 'length', false, 'min'=>5, 'length'=>32),
		);
		if(!$this->testRule(array('username'=>$username, 'password'=>$password), $rules)){
			$this->addError('数据验证失败', 1001);
			return false;
		}
		$Secrity = H::getObj('HSafety');
		//同一个IP之下1200秒内允许登录出错的次数 大于20次拒绝服务,大于30次 不再写入日志
		$ipTimes = $Secrity->ipTimes('ADMIN_LOGIN');
		if($ipTimes >20){
			if($ipTimes<30){
				$this->addError('请求次数过多,请稍后再试', 1002);
				CAdminLog::add('尝试登陆次数过多拒绝服务,用户名:'.$username);
			}
			return false;
		}
		$userInfo = $this->getRow(array('username'=>$username));
		$adminId = $userInfo===false ? 0 : $userInfo['id'];
		//图形验证码校验
		if(!$this->test($imgCode, 'imgcode')){
			$this->addError('图形验证码不正确', 1003);
			//写入日志
			CAdminLog::add('图形验证码不正确,用户名:'.$username, $adminId, null, $adminId);
			return false;
		}
		//校验密码签名
		if($userInfo === false){
			$this->addError('用户名或者密码不正确', 2001);
			CAdminLog::add('用户名不存在:'.$username, $adminId, null, $adminId);
			return false;
		}
		if($this->encryptPassword($password) != $userInfo['password']){
			$this->addError('用户名或者密码不正确', 2002);
			CAdminLog::add('密码错误,用户名:'.$username, $adminId, null, $adminId);
			return false;
		}
		if($userInfo['status']==0){
			$this->addError('您的用户名已被冻结,请联系管理员解冻', 2003);
			CAdminLog::add('登录被冻结的用户拒绝服务,用户名:'.$username, $adminId, null, $adminId);
			return false;
		}
		if($userInfo['is_delete']==1){
			$this->addError('用户名已被删除', 2004);
			CAdminLog::add('登录被删除的用户拒绝服务,用户名:'.$username, $adminId, null, $adminId);
			return false;
		}
		//登录一个用户
		H::user()->login($timeout);
		H::user()->set('id', $userInfo['id']);
		H::user()->set('username', $userInfo['username']);
		H::user()->set('is_super', $userInfo['is_super']);
		H::user()->set('realname', $userInfo['realname']);
		H::$SESSION['admin_id'] = $userInfo['id'];
		//设置可访问的路由
		if($userInfo['is_super']!=1){
			$config = H::getConfig('', 'access.php');//访问控制的配置
			$Menu = new CMenu();
			H::user()->set('routes', $Menu->getRoutes());//获取当前登录用户的特定路由
		}
		$Secrity->ipTimesClear('ADMIN_LOGIN');//登录成功销毁登录计数器
		//更新管理员登录信息
		CAdminLog::add('登录成功', $userInfo['id']);
		$newData = array('login_time'=>date('Y-m-d H:i:s'), 'login_count'=>$userInfo['login_count'] + 1);
		$this->updateByKey($newData, $userInfo['id']);
		return true;
	}
?>
关键词:用户验证 用户授权 权限授予 未登录跳转
阅读:3060 | 发布时间:2019-01-02 16:48