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(); } }