| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 | <?phpnamespace Cas\Module;use KIF\Data\ResultWrapper;use KIF\Verify;use KIF\Core\Config;use KIF\Exception\ParamsException;use KIF\Core\Request;use Cas\Dao\BackUser;/** *  * 后台管理通行证 * @author lishumingoo@gmail.com */class BackPassport {	/**	 * 	 * 安全key	 * @var string	 */	private $securityKey;		private $login_cookie_name = 'BACK_PASSPORT_MEMBER';		public function __construct() {		$PASSPORT_SIGN_KEY = Config::getInstance()->get('passport_sign_key');		if (!$PASSPORT_SIGN_KEY) {			throw new ParamsException('请指定securityKey');		}		$this->securityKey = $PASSPORT_SIGN_KEY;	}		/**	 *      * 登录     * @param string $name  用户名     * @param string $password  密码     * @param int | null $expire 登录有效期 值为null时:表示该cookie为当前会话期有效     * @return ResultWrapper     */	public function login($name, $password, $project, $expire = null) {		$objBackUser = new BackUser();		$tmpResult = $objBackUser->getByNameAndPassword($name, $password);		if (!$tmpResult->isSuccess()) {			return $tmpResult;		}		$user = $tmpResult->getData();						if ($user['permission'] != 'admin' && $user['project'] != $project) {			return ResultWrapper::fail('无权管理此项目');		}				$loginInfo = array(            'uid'		=> $user['uid'],		    'name'		=> $user['name'],		    'expire'	=> $expire,		);				return $this->writeLoginCookie($loginInfo);	}		/**	 * 	 * 推出登录	 */	public function logout() {		setcookie($this->login_cookie_name, '', 0, '/', $_SERVER['HTTP_HOST']);	}		/**	 * 	 * 注册	 * @param array $info	 * @return InternalResultTransfer	 */	public function register(array $info) {		if (isset($info['expire'])) {			$expire = $info['expire'];			if (!Verify::unsignedInt($expire)) {				$expire = null;			}			unset($info['expire']);		} else {			$expire = null;		}        $objBackUser = new BackUser();        $tmpResult = $objBackUser->add($info);        if (!$tmpResult->isSuccess()) {        	return $tmpResult;        }        $user = $tmpResult->getData();        $loginInfo = array(            'uid'             => $user['id'],            'uname'           => $user['name'],            'expire'          => $expire,        );        $tmpResult = $this->writeLoginCookie($loginInfo);        if (!$tmpResult->isSuccess()) {        	return $tmpResult;        }        return ResultWrapper::success($user);	}		/**	 * 	 * 获取登录用户信息	 * @return ResultWrapper 成功:存在登录cookie里的信息作为数组返回;失败:失败原因	 */	public function getLoginInfo() {		if (!isset($_COOKIE[$this->login_cookie_name])) {			return ResultWrapper::fail('没有登录cookie');		}		$loginCookie = $_COOKIE[$this->login_cookie_name];			$loginInfo = array();		parse_str($loginCookie, $loginInfo);			$tmpResult = $this->verifySign($loginInfo);		if (!$tmpResult->isSuccess()) {			return $tmpResult;		}			return ResultWrapper::success($loginInfo);	}		/**	 * 	 * 写登录信息到cookie	 * @param array $info	 * @return ResultWrapper	 */	public function writeLoginCookie(array $info) {		if (is_null($info['expire'])) {// 说明这是个当前会话期有效的登录用户			$info['expire']      = time() + 12 * 60 * 60;//登录cookie签名的有效性,设为4小时			$cookie_expire       = null;//让登录cookie在当前会话期有效		} else {			# 让登录cookie的存在期比 登录cookie签名有效性多1天。避免用户电脑时间与服务器时间不一致,导致签名在有效期,但cookie却已失效的情况。			$cookie_expire       = $info['expire'] + 24 * 60 * 60;		}			if (is_null($info['timestamp'])) {//			$info['timestamp'] = time();		}			# 版本号,为以后安全性升级做准备		$info['version'] = '0.2';			$tmpResult = $this->sign($info);		if (!$tmpResult->isSuccess()) {//签名失败			return $tmpResult;		}			$info['sign'] = $tmpResult->getData();			setcookie($this->login_cookie_name, http_build_query($info), $cookie_expire, '/', $_SERVER['HTTP_HOST']);			return ResultWrapper::success();	}		/**	 * 	 * 对 $info 做签名	 * @param array $info 格式:array (	 *     // 这些是必要字段	 *     'uid'       => (int),//用户id	 *     'uname'     => (string),//用户名	 *     'expire'    => (int),//签名有效期,过了这个有效期,即使签名正确,也不认。	 *     'register_type' => (int),//用户注册类型	 * )	 * @return ResultWrapper  成功:返回签名$sign;失败:返回失败原因	 */	public function sign(array $info) {		if (!isset($info['uid']) || !Verify::int($info['uid'])) {			return ResultWrapper::fail('无效的uid');		}			if (!isset($info['expire']) || !Verify::int($info['expire'])) {			return ResultWrapper::fail('无效的expire');		}			if (!isset($info['name']) || !is_string($info['name']) || empty($info['name'])) {			return ResultWrapper::fail('无效的name');		}			ksort($info);		$tmpStr = '';		foreach ($info as $k => $v) {			if ($v != '' && $k != 'sign') {				$tmpStr .= "{$k}={$v}&";			}		}		$tmpStr .= "securityKey={$this->securityKey}";		$sign = strtolower(sha1($tmpStr));		return ResultWrapper::success($sign);	}		/**	 * 	 * 验证 $info 的有效性	 * @param array $info	 * @return ResultWrapper	 */	public function verifySign(array $info) {		if (!isset($info['sign'])) {			return ResultWrapper::fail('没有指定sign值,无法校验');		}			$tmpResult = $this->sign($info);		if (!$tmpResult->isSuccess()) {			return $tmpResult;		}			$sign = $tmpResult->getData();		if ($sign != $info['sign']) {			return ResultWrapper::fail("给定的sign:{$info['sign']} 与 计算后的sign:{$sign} 不等");		}			if ($info['expire'] < time()) {			return ResultWrapper::fail('expire存储的签名有效期已过');		}			return ResultWrapper::success();	}}
 |