详解cookie和session原理

http协议是webserver服务端和client客户端相互通信的协议。它是一种无状态协议。所谓无状态就是指不会维护http请求数据,非持久的,即此次连接无法得到上次连接的状态。这样,用户从A页面跳转到B页面会又一次发送一此http请求,而服务端在返回相应的时候是无法获知该用户在请求B页面之前做了什么。为了将请求进行关联,做一些分析或者返回一些该用户信息等,会话技术cookie和session技术就产生了。

cookie:客户端浏览器的会话技术跟踪用户。所以客户端必须开启cookie,如果关闭将没法使用。所以有的网站比如百度云,如果浏览器没有开启cookie,会提示用户开启cookie。
一、工作原理:
服务器上的代码中使用了setCookie(‘username’,‘mary’)保存用户信息。
1.用户使用浏览器上网,当第一次访问某一个网站时,网站服务器会根据代码中所写的setCookie的一些信息,并将该信息通过响应头返回字段set-cookie,并且值为服务器端所设置的key,value。如下:
在这里插入图片描述
2.用户浏览器接收到该服务器端返回的请求头后,会看到set-cookie字段,然后浏览器会在它的本地cookie文件上加上一行key:value值。保存时会对中文进行urlencode编码如果服务器没有设置时间,当会话结束即浏览器关闭后,cookie失效。如下
在这里插入图片描述
3.当用户浏览器再次访问该网站时,浏览器会将保存在cookie中的值保存到请求头中,当服务器端接收到改请求后,查看有没有该cookie标识对应的用户,如果有的话就说明是同一用户进行的访问
在这里插入图片描述
二、设置cookie服务其端setcookie的设置参数:比如浏览器中的保存密码,一个地址下的帐号密码保存起来
官方文档
在这里插入图片描述

setcookie(string name, string value, int expire,string path, string domain, int secure,bool $httponly=false); 
 name: Cookie 名称
 value: Cookie 值。 这个值储存于用户的电脑里,请勿储存敏感信息。 比如 name 是 'cookiename', 可通过 $_COOKIE['cookiename'] 获取它的值。
 expire: Cookie 的过期时间。 这是个 Unix 时间戳,即 Unix 纪元以来(格林威治时间 1970 年 1 月 1 日 00:00:00)的秒数。 也就是说,基本可以用 time() 函数的结果加上希望过期的秒数。 或者也可以用 mktime()。 time()+60*60*24*30 就是设置 Cookie 30 天后过期。 如果设置成零,或者忽略参数, Cookie 会在会话结束时过期(也就是关掉浏览器时)。
 path: Cookie 有效的服务器路径。 设置成 '/' 时,Cookie 对整个域名 domain 有效。 如果设置成 '/foo/', Cookie 仅仅对 domain 中 /foo/ 目录及其子目录有效(比如 /foo/bar/)。 默认值是设置 Cookie 时的当前目录。
domain:  Cookie 的有效域名/子域名。 设置成子域名(例如 'www.example.com'),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。 要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 'example.com')
secure: 设置这个 Cookie 是否仅仅通过安全的 HTTPS 连接传给客户端。 设置成 TRUE 时,只有安全连接存在时才会设置 Cookie。 如果是在服务器端处理这个需求,程序员需要仅仅在安全连接上发送此类 Cookie (通过 $_SERVER["HTTPS"] 判断)。
httponly: 设置成 TRUE,Cookie 仅可通过 HTTP 协议访问。 这意思就是 Cookie 无法通过类似 JavaScript 这样的脚本语言访问。 要有效减少 XSS 攻击时的身份窃取行为,可建议用此设置(虽然不是所有浏览器都支持),不过这个说法经常有争议。 PHP 5.2.0 中添加。 TRUE 或 FALSE

例子:setcookie("TestCookie", $value, time()+3600, "/~rasmus/", "example.com", 1);   //一小时过期
<?php
// 设置 Cookie
setcookie("cookie[three]", "cookiethree");
setcookie("cookie[two]", "cookietwo");
setcookie("cookie[one]", "cookieone");

// 网页刷新后,打印出以下内容。网页刷新就等于第二次访问了,浏览器就可以带上cookie。第一次访问打印不出内容,因为第一次访问服务器才设置cookie,然后返回。
if (isset($_COOKIE['cookie'])) {
    foreach ($_COOKIE['cookie'] as $name => $value) {
        $name = htmlspecialchars($name);
        $value = htmlspecialchars($value);
        echo "$name : $value <br />\n";
    }
}
?>

三、取回cookie : 使用PHP全局变量$_COOKIE取回
四、删除cookie:就是让过期时间设置成过去的时间

方法一 将cookie的生存时间默认为空,仅导入第一个参数,后面的所有列省略,则生存期限与浏览器一样,关闭浏览器时cookie就会自动删除
setcookie("user_name");
方法二 设置过期时间为一个小时前
setcookie("user_name", "", time() - 3600, "/~rasmus/", "example.com", 1);

五、cookie带来的问题
1.用户隐私问题。网站能通过我们提交的cookie知道该用户做过的事情
2.信息安全问题。服务器并没有对浏览器提交的cookie进行必要的检查,没有检查是否是原主机发送,所以如果别人拿到了cookie,那么就可以冒充我们去做一些事情
六、如果浏览器不支持COOKIE怎么办?
在这里插入图片描述

session:服务器端的会话技术。为每一个访问者创建唯一的id(UID)(而且同一用户不同的浏览器也会生成不同的UID),并基于这个id(UID)来存储变量。UID存储在cookie中,亦或者通过URL进行传导
一、工作原理:
1.当用户浏览器第一次访问网站服务器时,服务器中确保有设置session的代码,那么服务器请求头header中会返回一个字段set-cookie,字段值为PHPSESSID=hfuaeua4134afavasf
2.用户浏览器接收到相应头后,会在本地保存一个cookie,key为PHPSESSID,value为hfuaeua4134afavasf
3.当用户进行下一次请求时,请求头header中会携带cookie,即会把2中设置的键和值都携带上
4.服务器接收到请求后,在请求头中可以获取到PHPSESSID,说明浏览器支持cookie,并保存了PHPSESSID的值,这样可以通过PHPSESSID的值去保存session的文件中通过$_SESSION获取保存的值
二、具体步骤
开启session会话

session_start()
当服务器代码中只写了session_start()后,即使不写下面的代码,会做的两件事:
1.给用户分配一个UID,返回浏览器一个PHPSESSID以及值hfuaeua4134afavasf,值是服务器自动生成的不需要管
   问:为什么返回的名字为PHPSESSID呢?
   答:因为在php.ini配置中,有个参数规定了 session.name = PHPSESSID //默认值PHPSESSID,当然这个名字可以修改
2.在服务器中生成一个session文件
   问:为什么生成文件?
   答:因为在php.ini配置中,有参数规定session.save_handler= files    //默认保存在文件中,可以改比如resis,user(改为user是用户自定义的方法,比如保存在数据库中,但是具体的保存数据库的代码增删改查需要自己写个session类)
   参考:https://blog.csdn.net/u013707844/article/details/26475265
   问:文件在哪呢?
   答:文件在php.ini配置中,有个参数规定了session.save_path = '/'    //在根目录下,也可以修改,如果上面改为redis,那么save_path为tcp://127.0.0.1:6379保存redis   的服务器
   问:生成的文件名字叫什么呢?
   答:叫sess_hfuaeua4134afavasf,后面跟的字符就是PHPSESSID的值       
这是php的session机制实现的,我们不需要管。

设置session值

$_SESSION,新建值和修改值都使用$_SESSION,修改时重新赋值一边就可以
$_SESSION['user_name'] = 'bob'
$_SESSION['user_id'] = 2
这一步会将user_name,user_id写入文件中,保存形式为:user_name | s:3 : "bob";user_id | i :2  
解释:s为user_name为string,长度为3,两个之间使用逗号隔开,i为Int类型,Int型没有长度

销毁session,比如退出登录

1. setcookie(session_name(),session_id(),time() -8000000,..);//退出登录前执行,删除的是浏览器保存的cookie(PHPSESSID)
    注:函数session_name()可以获取到服务器配置中配置的名字
        函数session_id()可以获取到服务器分配给的唯一的UID,即PHPSESSID的值
2. usset($_SESSION);//这会删除所有的$_SESSION数据,刷新后,如果没有删除浏览器的cookie(PHSESSID),有COOKIE传过来,但是没有数据。
3. session_destroy();//这个作用更彻底,删除$_SESSION 删除session文件,和session_id
其中因为1中浏览器没有cookie传过来所以不会开启session获取到session的值,2是将文件中的值都删除但文件还在,3是将文件删除以及session_id()
  所以2和3还是会有cookie传过来,只是在保存的session中找不到数据了。可以把浏览器的cookie也删除,因为浏览器保留这个cookie也没用了

session的配置以及配置中的优化

session.cookie_path = ''    //访问的路径
session.cookie_domain =   host  //不用动,默认为host
session.cookie_httponly = 1     //开启httponly
session.auto_start = 0        //默认开启session,如果不开启,那么session_start没用
session_start()开启后会开启垃圾回收,但不是php自身的垃圾回收机制,session回收是需要删除文件,因为网站可能生成成百上千个文件,如果过期了,还要删除,所以这个概率机制实在php.ini中的配置决定的。
在配置文件php.ini中配置  gc  : garbage collection
session.gc_probability =1  //值为0的话就是0/除数等于0 即没有这个垃圾回收,需要自己写脚本进行删除
session.gc_divisor =1000   //gc的除数
session.gc_maxlifetime =1440   //过期时间 默认24分钟
概率是 session.gc_probability/session.gc_divisor 结果 1/1000, 每一千个用户调用session_start时,就会执行删除过期的session,根据网站的访问进行设置
不建议设置过小,因为session的垃圾回收,是需要检查每个文件是否过期的。

关闭cookie能使用session吗?
能,可以将PHPSESSID拼到url中访问服务器
session共享?
保存在数据库或者缓存redis中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值