您的位置:首页 > 理论基础 > 计算机网络

http cookie session 介绍 原理以及使用

2019-03-14 10:14 357 查看

http协议

http

超文本传输协议,无连接,无状态,

访问链接时,http request 发送请求服务器

http response 响应请求,请求时建立链接,请求完成关闭链接

keep-alive http持久连接,节省时间,无状态的所以没有保存信息,每次传输都需要传输很大的数据,所以有了会话控制,让服务器知道我们从一个页面跳转过后,还知道连接的请求来源是谁

会话控制

cookie

保存方式

内存cookie:浏览器关闭后消失

硬盘cookie:保存在硬盘里,可以设置过期时间,除非过期或手工删除,否则是不会消失的

使用场景(永久登录,购物车)

浏览器的小文件保存在硬盘中,服务器端设置,可以通过http响应头返回给浏览器,在响应头中加入字段 setCookie,

每个浏览器都有独立空间放cookie,在服务器向用户发送网页的同时,也会发送cookie,记录商品信息,访问另外页面时,浏览器把cookie通过header发送给服务器,于是服务器知道我们访问了哪些商品,继续选购,服务器在原来的基础上继续追加新的数据,信息,结账时,把cookie中进行结算

登录的时候,自动登录,自动填充用户名和密码,第一次登录时候服务器发送了用户凭证到硬盘中,后续登录,客户端将其一并发送到服务器,服务器验证是否为合法用户

https://www.geek-share.com/detail/2706605063.html

操作cookie

设置cookie

setcookie("userinfo", "status=1", time()+20, '/practice', '', true);
setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] ) : bool
$name 名称
$value 内容
$expire 过期时间 过期时间如果为0,则为内存cookie,关闭则过期
$path 保存目录
$domain 作用域
$secure 是否安全(https)
$httponly 是否只使用http操作cookie,默认false,true则不可以用js操作cookie,可以减少xss攻击

setawcookie 不会对值 进行urlencoding编码

读取cookie

$_COOKIE

更新cookie

保持其他参数一样即可更新
setcookie("userinfo", "status=1", time()+10, '/practice');
setcookie("userinfo", "zhangsanfeng", time()+10, '/practice');

删除cookie

把时间设置为已经过期的时间,其他参数也需要一样,保证$path 和 $domain 和之前的保持一致
setcookie("userinfo", "", time()-1, '/practice');
通过header 操作cookie
header("Set-Cookie:name=value[;expires=date][;domain=domain][;path=path"][;secure][;httponly]);
header('set-Cookie: b=2;expires='.gmdate('D, d M Y H:i:s \G\M\T', time()+3600).'; domain=.test.com');
header('set-Cookie: b=2; path=/test; domain=.test.com; secure; httponly;');
cookie保存数组形式
setcookie('userInfo[name]', 'zhangsan', strtotime("+7 days"));
setcookie('userInfo[sex]', 'man', strtotime("+7 days"));
js 操作cookie
var Cookie = {
set : function (key, val, expiresDays) {
if (expiresDays) {
var date = new Date();
date.setTime(date.getTime()+expiresDays*24*3600*1000);
var expiresStr="expires="+date.toGMTString()+';';
}else{
var expiresStr = '';
}
document.cookie = key + '=' + escape(val)+';' + expiresStr;
},
get : function(key){
var getCookie = document.cookie.replace('/[ ]/g', '');
var resArr = getCookie.split(';');
var res;
for (var i = 0, len = resArr.length; i < len; i++){
var arr = resArr[i].split('=');
if (arr[0] == key) {
res = arr[1];
break;
}
}
return unescape(res);
}
}
自动登录
//判断前台自动登录是否选中...
$row = mysqli_fetch_assoc($result);
if ($autologin == 1){
setcookie('username', $username, strtotime('+7 days'));
$salt = 'testsalt';
$auth = md5($username.$password.$salt).':'.$row['id'];
setcookie('auth', $auth, strtotime('+7 days'));
}else{
setcookie('usernmae', $username);
}
//选中了保存cookie登录成功后,关闭浏览器,再次访问的时候,直接访问页面cookie不会消失,此时用cookie中的用户名在数据库中进行查找,然后按照一样的加密规则和cookie中的auth进行比对,如果一致,则直接实现登录效果
//...
cookie操作类的封装
<?php

class CustomCookie{
static private $_instance = null;
private $expire = 0;
private $path = '';
private $domain = '';
private $secure = false;
private $httponly = false;

/**
* 构造函数完成cookie参数初始化工作
*/
private function __construct(array $options = []){
$this->setOptions($options);
}

private function setOptions(array $options){
if (isset($options['expire'])) {
$this->expire = (int)$options['expire'];
}
if (isset($options['path'])) {
$this->path = $options['path'];
}
if (isset($options['domain'])) {
$this->domain = $options['domain'];
}
if (isset($options['secure'])) {
$this->secure = (bool)$options['secure'];
}
if (isset($options['httponly'])) {
$this->httponly = (bool)$options['httponly'];
}
}
/**
* 单例模式
* @param [array] $options Cookie相关选项
* @return object 对象实例
*/
public static function getInstance(array $options = []){
if (is_null(self::$_instance)) {
$class = __CLASS__;
var_dump($class);
self::$_instance = new $class($options);
}
return self::$_instance;
}

/**
* Undocumented function
*
* @param [string] $name cookie名称
* @param [string] $value cookie值
* @param array $options cookie设置参数
* @return void
*/
public function set(string $name,mixed $value, array $options=[]){
if (is_array($options) && count($options) > 0){
$this->setOptions($options);
}
if(is_array($value) || is_object($value)){
$value = json_encode($value, JSON_FORCE_OBJECT);
}
setcookie($name, $value,$this->expire,$this->path, $this->domain, $this->secure, $this->httponly);
}

public function get(string $name){
if (isset($_COOKIE[$name])){
return substr($_COOKIE[$name],0,1) == '{' ? json_decode($_COOKIE[$name], true) : $_COOKIE[$name];
}else{
return null;
}
}

public function del(string $name, array $options = []){
if (is_array($options) && count($options) > 0){
$this->setOptions($options);
}

if (isset($_COOKIE[$name])){
setcookie($name, '', time()-1,$this->path, $this->domain, $this->secure, $this->httponly);
unset($_COOKIE[$name]);
}
}

public function delAll(){
if (is_array($options) && count($options) > 0){
$this->setOptions($options);
}

if(!empty($_COOKIE)){
foreach ($_COOKIE as $key => $value) {
setcookie($key, '', time()-1,$this->path, $this->domain, $this->secure, $this->httponly);
unset($_COOKIE[$key]);
}
}
}
}
$res =  CustomCookie::getInstance();
$res->set('user', '111',['expire'=>strtotime("+1 days"),'path'=>'/']);
$res->set('userInfo', ['name'=>'zhangsan','age'=>10]);
var_dump($res->get('userInfo'));
cookie的弊端

不要存储敏感数据,不安全,劫取cookie之后可以用来cookie欺骗

不要把cookie当做客户端的存储容器,首先每个域名允许的cookie有限制,根据不同浏览器限制不同,最大可以存储4k

cookie设置之后 每次都会附着在http header中一起发送,浪费带宽

localStorage

设置:localStorage.setItem(key,value)

读取:localStorage.getItem(key)

删除指定:localStorage.removeItem(key)

全部删除:localStorage.clear()

获取指定的键名:localStorage.key(i)

如果为json对象需要先转成字符串:localStorage.setItem(‘userinfo’,JSON.stringify(userinfo))

取出的时候:JSON.parse(localStorage.getItem(userinfo))

特性
生命周期 有服务端生成,可设置失效时间。如果在浏览器生成cookie,默认关闭浏览器失效 除非清除,否则永久保存 仅在当前会话有效,关闭浏览器或页面清除
存放大小 4k左右 5MB 5MB
与服务器通信 每次都会携带http偷,如果使用cookie过多数据会带来性能问题 客户端浏览器保存,不参与服务器通信 客户端浏览器保存,不参与服务器通信
易用性 需要自己封装,原生cookie接口不友好 源生接口可以接受,也可以再次封装对object array良好支持 源生接口可以接受,也可以再次封装对object array良好支持
使用场景 存在客户端,管理购物车,h5游戏 存在客户端,管理购物车,
Custom_LocalStorage = {
set : function (key, value){
var item = {
data:value
}
localStorage.setItem(key, JSON.stringify(item));
},

get : function(key) {
var val = localStorage.getItem(key);
if (!val) return null;
val = JSON.parse(val);
return val;
}
}

session

什么是session

持续性的双向的连接 ,服务器和浏览器的保持链接的这段时间

session工作原理


理发店会员卡:发卡

开始会话:php尝试在请求中查找会话id,如果不包含就创建新的会话,表示第一次,会话开始之后,php就把数据保存到变量里$_SESSION,并将其序列化然后发送给会话保存管理器,默认的会话保存管理器是以文件的形式保存,

  1. 准备建立会话的时候,php会先查看请求中是否包含session_id,如果没有 服务器,服务器会在内存里创建变量,这个变量就是session_id(session_1234),
  2. 服务器会把session_id发送到浏览器保存,一般是保存到cookie中
  3. 以后每次浏览器访问服务器时候,都会携带cookie中存在的session_id(session_1234),这样服务器就认识这个浏览器了
  4. 服务器端的session_1234 可以存放任意的会话数据,这些数据是经过序列化之后存放进去的
  5. 每次浏览器访问服务器都可以凭借自己的session_id 到服务器的变量中认领信息
  6. 如果想销毁会话,可以删除掉会话中的数据,还可以销毁会话文件
php中如何使用会话

开启会话 session_start()

设置 $_SESSION

销毁 session_destory()

session名字 session_name()

session的ID session_id()

使用session的生存周期,通过cookie来实现

//设置好后可以实现使用session 但是关闭浏览器不过期
setcookie(session_name(),session_id(),time()+3600, '/');
session禁用传递session_id

在url中传参 http://localhost/test.php?session_name()=session_id

在第二个页面中 获取session_id($_GET[session_name()]);

销毁会话
  1. 将$_SESSION 清空

    $_SESSION = [];

  2. 将cookie中的数据清除

    setcookie()

  3. 销毁会话

    session_destory()

// 初始化会话。
// 如果要使用会话,别忘了现在就调用:
session_start();

// 重置会话中的所有变量
$_SESSION = array();

// 如果要清理的更彻底,那么同时删除会话 cookie
// 注意:这样不但销毁了会话中的数据,还同时销毁了会话本身
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}

// 最后,销毁会话
session_destroy();
自定义会话管理器

session_set_save_handler() 设置用户自定义会话存储

<?php

CREATE TABLE `sessions` (
`session_id` char(32) NOT NULL,
`session_data` varchar(255) NOT NULL,
`session_expire` varchar(255) NOT NULL,
PRIMARY KEY (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

class CustomSession implements SessionHandlerInterface
{
private $link;
private $lifetime;
public function open($savePath, $session_name){
$this->lifetime = get_cfg_var('session.gc_maxlifetime');
$this->link = mysqli_connect('localhost', 'root', 'root');
mysqli_set_charset($this->link, 'utf8');
mysqli_select_db($this->link, 'session_test');
if ($this->link){
return true;
}
return false;
}

public function close(){
mysqli_close($this->link);
return true;
}

public function read($session_id){
$session_id = mysqli_escape_string($this->link, $session_id);
$sql = "SELECT * FROM sessions WHERE session_id = '{$session_id}'";
$result = mysqli_query($this->link, $sql);
if(mysqli_num_rows($result) == 1){
return mysqli_fetch_assoc($result)['session_data'];
}
return '';
}

public function write($session_id, $session_data){
$session_id = mysqli_escape_string($this->link, $session_id);
$sql = "SELECT * FROM sessions where session_id = '{$session_id}'";
$result = mysqli_query($this->link, $sql);

$newExp = time() + $this->lifetime;
var_dump($newExp);
var_dump(mysqli_num_rows($result));
if(mysqli_num_rows($result) == 1){
$sql = "UPDATE sessions SET session_expire='{$newExp}', session_data = '{$session_data}' where session_id = '{$session_id}'";
}else{
$sql = "INSERT sessions VALUES('{$session_id}','{$session_data}','{$newExp}')";
}
mysqli_query($this->link, $sql);
return mysqli_affected_rows($this->link) == 1;
}

public function destroy($session_id){
$session_id = mysqli_escape_string($this->link, $session_id);
$sql = "DELETE FROM sessions WHERE session_id = '{$session_id}'";
mysqli_query($this->link, $sql);
return mysqli_affected_rows($this->link) == 1;
}

public function gc($maxlifetime){
$sql = "DELETE FROM sessions WHERE session_expires <" . time();
mysqli_query($this->link, $sql);
if (mysqli_affected_rows($this->link) > 0) {
return true;
}
return false;
}
}

// 使用说明:new之后,要设置保存方式为用户
// require_once 'CustomSession.php';
// 要实现接口中的所有方法,才能使用
$customsession = new CustomSession;

ini_set('session.save_handler', 'user');
session_set_save_handler($customsession, true);

session_start();
$_SESSION['user_name'] = 'liming';
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐