php 登入

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baixiaoshi/article/details/9027829
今天碰到一个session_id的认识

首先要明白PHPSESSID看似多次刷新都不会改变其实是没有删除本地相关联的cookie,删除的方法

session_destroy();//删除服务器端的session文件

setcookie(session_name(),'',time()-3600,'/');//删除本地相关联的cookie

session_unset();//清空内存中的cookie或者是$_SESSION = array(); 

然后再刷新相应的页面你就会看到PHPSESSID会发生变化了,根据此可以得:如果session文件已经创建则不重新生成PHPSESSID,否则需要重新生成,生成规则,就看下边喽……!

 

--------------------------------------------------------------------------------------------------------------------------------------

现在经过测试应该是不是检测session文件是否存在,而是检测PHPSESSID的cookie是否存在并且是否未过期!特此更正!

------------------------------------------------------------------------------------------------

可能PHP开发者心中多少都思考过这么两个问题:

种植在客户端浏览器中的PHPSESSIONID会出现重复吗?
PHPSESSIONID安全性如何,有没可能被黑客轻易的仿造呢?
带上这个问题,我稍微注意了一下PHP的源码后,疑问也就有了答案。

PHP在使用默认的 session.save_handler = files 方式时,PHPSESSIONID的生产算法原理如下:


hash_func = md5 / sha1 #可由php.ini配置
PHPSESSIONID = hash_func(客户端IP + 当前时间(秒)+ 当前时间(微妙)+ PHP自带的随机数生产器)

从以上hash_func(*)中的数据采样值的内容分析,多个用户在同一台服务器时所生产的PHPSESSIONID重复的概率极低(至少为百万份之一),设想,但台动态Web Server能到2000/rps已经很强悍了。

另外,黑客如果要猜出某一用户的PHPSESSIONID,则他也必须知道“客户端IP、当前时间(秒、微妙)、随机数”等数据方可模拟。

以下是截取PHP源码中PHPSESSIONID实现片段:

gettimeofday(&tv, NULL);

if (
zend_hash_find(&EG(symbol_table), "_SERVER", sizeof("_SERVER"), (void **) &array) == SUCCESS &&
Z_TYPE_PP(array) == IS_ARRAY && zend_hash_find(Z_ARRVAL_PP(array), "REMOTE_ADDR", sizeof("REMOTE_ADDR"), (void **) &token) == SUCCESS)
{
    remote_addr = Z_STRVAL_PP(token);
}


spprintf(&buf, 0, "%.15s%ld%ld%0.8F", remote_addr ? remote_addr : "", tv.tv_sec, (long int)tv.tv_usec, php_combined_lcg(TSRMLS_C) * 10);

switch (PS(hash_func))
{
case PS_HASH_FUNC_MD5:
    PHP_MD5Init(&md5_context);
    PHP_MD5Update(&md5_context, (unsigned char *) buf, strlen(buf));
    digest_len = 16;
    break;
case PS_HASH_FUNC_SHA1:
    PHP_SHA1Init(&sha1_context);
    PHP_SHA1Update(&sha1_context, (unsigned char *) buf, strlen(buf));
    digest_len = 20;
    break;
default:
    php_error_docref(NULL TSRMLS_CC, E_ERROR, "Invalid session hash function");
    efree(buf);
    return NULL;
}

<?php
  

  if (empty($_SESSION)) {
      session_start();
  }


  function login() {

      $_SESSION['name'] = 'baixiaoshi';
      $_SESSION['age'] = 26;
      setcookie("token", "hahahahahah", time() + 10, "/", "test.cc");
  }

  function loginout() {
      if (isset($_SESSION)) {
          unset($_SESSION);
      }

      setcookie("token", "hahahahahah", time() - 10, "/", "test.cc");

      setcookie(session_name(), "", time() - 10);
      session_destroy();
  }

  function autologin() {
    loginout();

    if (empty($_SESSION)) {
      session_start();
    }
    login();
  }

  $sessionid = session_id();
echo '######start########';
if (isset($_SESSION)) {
    echo '<pre>';
    print_r($_SESSION);
    echo '</pre>';
    echo 'sessionid=' . $sessionid;
}
echo '######end########';

$flag = $_GET['flag'];
if ($flag == 1) {
    login();
} else if ($flag == 2) {
    autologin();
}
if (isset($_SESSION)) {
    echo '<pre>';
    print_r($_SESSION);
    echo '</pre>';
    echo 'sessionid=' . $sessionid;
}




<?php
namespace Services\Admins;

use Services\BaseService;
use Tools\Result;
use Dao\AdminDao;
use Yaf\Session;

class AdminService extends BaseService
{
    private $adminDao;
    private $session;
    //用户设置的session过期时间,php文件方式默认是1440秒过期
    public static $USER_SESSION_EXPIRE = 10;
    public function __construct()
    {
        $this->adminDao = AdminDao::getInstance();
        $this->session = Session::getInstance();
    }

    /**
     * 判断用户是否登入
     * @param $cookieToken
     * @return Result
     */
    public function isLogin($cookieToken)
    {   
        echo '<br/>#########isLogin start #########';
        echo '<br/>cookieToken=' . $cookieToken;
        $result = new Result();
        if (empty($cookieToken)) {
            $result->message = '会话过期,请重新登入';
            return $result;
        }
        $expire = $this->session->get('expire');
        $hashToken = $this->session->get('hashToken');

        echo '<br/>expire=' . $expire;
        echo '<br/>hashToken=' . $hashToken;

        if (!empty($hashToken) && !empty($cookieToken) && $cookieToken != $hashToken) {
            $result->message = 'token被篡改了';
            return $result;
        }

        if (empty($expire) || time() > $expire) {
            $admin = $this->adminDao->getByToken($cookieToken);
            echo '<br/>admin:';
            print_r($admin);
            if (empty($admin)) {
                $result->message = '会话过期,请重新登入';
                return $result;
            }
            //如果token还在有效期内
            if (!empty($admin) && time() > $admin['expire']) {
                $result->message = '会话过期,请重新登入';
                return $result;
            }
            $this->loginOut();
            session_start();
            $this->autoLogin($cookieToken, $admin);
        }

        $result->success = true;
        $result->message = 'login ok';
        return $result;
    }

    /**
     * 登入操作
     * @param $username
     * @param $password
     * @return Result
     */
    public function login($username, $password)
    {
        $result = new Result();
        $adminDao = $this->adminDao->getByName($username);
        if (empty($adminDao)) {
            $result->message = '该用户不存在';
            return $result;
        }

        if (md5($password) != $adminDao['password']) {
            $result->message = '密码错误';
            return $result;
        }
        $hashToken = $this->genHashToken($username, $password);
        $data = $this->operateLoginInfo($adminDao['id'], $hashToken);

        $result->success = true;
        $result->message = '登入成功';
        $result->data = $data;
        return $result;
    }

    /**
     *
     * 一天之内自动登入
     * @param $cookieToken
     * @return Result
     */
    public function autoLogin($cookieToken, $admin)
    {   
        echo '<br/>#######autoLogin start ##########';
        $result = new Result();
        $data = $this->operateLoginInfo($admin['id'], $cookieToken);
        $result->success = true;
        $result->message = '登入成功';
        $result->data = $data;
        return $result;
    }
    /**
     * 写入登入信息
     * @param $uid
     * @return bool
     */
    private function operateLoginInfo($uid, $hashToken)
    {
        //写入登入信息
        $time = time();
        $data = [];
        $expire = $time + self::$USER_SESSION_EXPIRE;
        //写入session
        $this->session->expire = $expire;
        $this->session->uid = $uid;
        $this->session->hashToken = $hashToken;

        //更新数据库中的数据, 设置一天免登入
        //$cookieExpire = $time + 24 * 3600;
        $cookieExpire = $time + 20;
        setcookie("hashToken", $hashToken, $cookieExpire, "/", "yaf.cc");

        var_dump($this->session->expire, $this->session->uid, $this->session->hashToken);

        $affectedRows = $this->adminDao->updateById($uid, $hashToken, $cookieExpire, $time);
        if (!$affectedRows) {
            return $data;
        }
        $data['hashToken'] = $hashToken;
        $data['expire'] = $expire;

        return $data;
    }


    /**
     * 校验登入的参数
     * @param $username
     * @param $password
     * @param string $vcode
     * @return Result
     */
    public function verifyLoginParams($username, $password, $vcode = '')
    {
        $result = new Result();
        $verifyCode = $this->session->get('verifyCode');
        if (strtolower($verifyCode) != $vcode) {
            $result->message = '验证码错误';
            return $result;
        }

        if (empty($username) || empty($password)) {
            $result->message = '用户名或密码不能为空';
            return $result;
        }

        if (strlen($username) < 6 || strlen($username) > 16) {
            $result->message = '用户名必须是6到16个字符';
            return $result;
        }

        if (strlen($password) < 6 || strlen($password) > 16) {
            $result->message = '密码必须是6到16个字符';
            return $result;
        }

        $result->success = true;
        $result->message = '参数校验通过';
        return $result;
    }

    /**
     * 退出
     * @return bool
     */
    public function loginOut()
    {
        if ($this->session->has('expire')) {
            $this->session->del('expire');
        }

        if ($this->session->has('uid')) {
            $this->session->del('uid');
        }
        if ($this->session->has('hashToken')) {
            $this->session->del('hashToken');
        }
        if (isset($_SESSION)) {
            setcookie(session_name(), '', time() - 3600, '/');
            setcookie("hashToken", '', time() - 3600, "/", "yaf.cc");
            session_destroy();
        }

        return true;
    }

    /**
     * 获取登入之后的信息
     * @param $cookieToken
     * @return Result
     */
    public function getLoginInfo($cookieToken)
    {
        $result = new Result();
        $isLogin = $this->isLogin($cookieToken);
        if (!$isLogin->success) {
            $result->message = $isLogin->message;
            return $result;
        }
        $data = [];
        $data['uid'] = $this->session->get('uid');
        $data['hashToken'] = $this->session->get('hashToken');
        $data['expire'] = $this->session->get('expire');

        $result->success = true;
        $result->message = 'ok';
        $result->data = $data;

        return $result;
    }

    /**
     * 生成登入的token
     * @param $username
     * @param $password
     * @return string
     */
    private function genHashToken($username, $password)
    {
        return md5($username . $password . time());
    }
}








展开阅读全文

没有更多推荐了,返回首页