| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 | <?phpnamespace Cas\Module;use KIF\Exception\ParamsException;use KIF\Core\Config;use KIF\Data\ResultWrapper;use KIF\Core\Request;use KIF\Verify;/** *  * 用户通行证 * @author lishumingoo@gmail.com */class Passport {		/**	 * 安全key	 * @var string	 */	private $securityKey;		private $login_cookie_name = 'TM_PASSPORT_MEMBER';		/**	 * 登陆类型之:未授权	 * @var unknown	 */	const LOGIN_TYPE_NOT_AUTH = '1';		/**	 * 登陆类型之:已授权	 * @var unknown	 */	const LOGIN_TYPE_HAS_AUTH = '2';			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;	}		/**	 * 登陆	 */	public function login() {}		/**	 * 注册	 * @param array $info	 */	public function register(array $info) {}		/**	 * 获取登录用户信息	 * @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() + 4 * 60 * 60;//登录cookie签名的有效性,设为4小时			$cookie_expire       = null;//让登录cookie在当前会话期有效		} else {			# 让登录cookie的存在期比 登录cookie签名有效性多1天。避免用户电脑时间与服务器时间不一致,导致签名在有效期,但cookie却已失效的情况。// 			$cookie_expire       = $info['expire'] + 24 * 60 * 60;			$cookie_expire       = $info['expire'];		}		if (is_null($info['timestamp'])) {//			$info['timestamp'] = time();		}		# 版本号,为以后安全性升级做准备		$info['version'] = '0.1';        $tmpResult = $this->sign($info);        if (!$tmpResult->isSuccess()) {//签名失败        	return $tmpResult;        }        $info['sign'] = $tmpResult->getData();        setcookie($this->login_cookie_name, http_build_query($info), $cookie_expire, '/', Request::rootDomain());        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['nickname']) || !is_string($info['nickname']) || empty($info['nickname'])) {// 			return ResultWrapper::fail('无效的uname');// 		}			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();	}	}
 |