cookie,session,Local Storage,Session Storage的重新认识

cookie

cookie认识

Cookie英文是曲奇饼、小甜品的意思。Cookie存放在客户端,通常需要与后台进行交互,后台设置cookie,然后存放在客户端,在客户端保存的是字符串,如下

image

cookie常用于网站的用户登录,将用户id存放到cookie中(用户id得加密),每次请求其他api时判断该cookie是否存在,如果存在则用户已登录,如果不存在则代表用户没有登录。

要知道,cookie必须在同一网站下且cookie的path路径为当前url或者是当前url的父级时才是共享的,具体内容看我下篇文章

cookie分为俩种

  • 第一种:cookie没有设置过期时间
setcookie('userId','4343');

如果是未设置过期时间的cookie,那么用户只要关闭浏览器(注意是关闭浏览器是不是关闭标签页)就会清除该cookie,并不会保持客户端状态。这种cookie也可以叫做session类的cookie,session顾名思义就是会话控制,则说明该cookie只在本次会话中有效,下次会话则会销毁

image

由于不能保持客户端状态,所以如果使用这种登录方式的话,用户只要退出浏览器就得重新登录
为了验证,我们做以下测试
1.随便定义一个接口,接口内容如下

public function index(Request $request)
    {
        setcookie('userId','4343');
        dd($_COOKIE['userId']);
    }

浏览器访问如下


image

2.屏蔽代码中的setcookie

public function index(Request $request)
    {
        //setcookie('userId','4343');
        dd($_COOKIE['userId']);
    }

我们关闭退出浏览器,重新访问上述接口,发现userId这个cookie已经不存在,随着关闭浏览器而销毁了

image

  • 第二种:cookie设置了过期时间
setcookie('userId','4343',time()+3600);

如果是设置了过期时间的cookie,那么该cookie是存在物理内存中,也就是关闭浏览器后该cookie并不会被删除,只有该cookie过期后才失效。也就是说重新打开该网站后,还可以重新获取到该cookie(未过期的前提下)。可以看到该cookie的expires此时为过期时间而不是第一种不设置过期时间时显示的session

image

由于这种方式是可以保持客户端状态的,所以如果使用这种登录方式的话,用户在关闭浏览器后,重新打开时,如果cookie没有过期的前提下,用户时仍然保持登录状态的的。

我们看到幕课网登录时有一个7天内自动登录的选项,选中登录之后在7天内是可以保持登录状态的,此处就是设置cookie在7天后过期,使用的是我们第二种方式。而如果不选中的话,退出浏览器后再次进入时需要重新登录,使用的是我们第一种方式

为了验证是否能保持客户端状态,我们同样做以下实验
1.随便定义一个接口,接口内容如下

public function index(Request $request)
    {
        setcookie('userId','4343',time()+3600);
        dd($_COOKIE['userId']);
    }

浏览器访问如下


image

2.屏蔽代码中的setcookie

public function index(Request $request)
    {
        //setcookie('userId','4343');
        dd($_COOKIE['userId']);
    }

我们关闭退出浏览器,重新访问上述接口,发现userId这个cookie仍然存在,仍然可以访问,并没有随着浏览器的关闭而销毁

image

cookie优点

  • 设置带过期时间的cookie,此cookie不会因会话结束或者客户端关闭而销毁,可以保持客户端状态。而session则没有该功能。

cookie缺点

  • Cookie因为是暴露在客户端的,所以相对不安全,容易被盗取,泄露个人隐私,如果必须存放cookie的话必须得加密;
  • Cookie数量控制在20个以内,每个cookie值的大小控制在4kb以内,而且每次都会携带在http头里面,如果cookie保存过多会带来性能损耗,为了解决这个问题我门可以使用下面介绍的local Storage
  • Cookie必须依赖于客户端,客户端(浏览器)如果关闭Cookie,则无法使用cookie。慕课网登录同样是使用cookie,如果禁用cookie之后,提示登录异常
    image

cookie常用方法

  • 创建cookie
//建议使用第一种
setcookie('userId','4343',time()+3600);
//使用$_COOKIE赋值时,该cookie不会在控制台中的cookie显示且不能设置过期时间
$_COOKIE['userId']=4343
  • 修改cookie
    同创建cookie
  • 查询cookie
//查询所有cookie
$_COOKIE
//查询单独cookie
$_COOKIE['userId]
  • 删除cookie
setcookie('userId','',time()-1);

session

session认识

session上面已经说了,顾名思义为会话。只有同一会话内的session才会共享。

那么怎么判定是同一会话呢?答案就是:session_id,后台可通过查看session_id()函数获取值,也就是说同一个session_id的session才会共享。

那么session_id又是什么呢?看下php.ini中的这段配置,大概可以知道session_id默认是一个名为PHPSESSID的cookie,session实现需要依赖cookie。

; Whether to use cookies.
; http://php.net/session.use-cookies
session.use_cookies = 1
; Name of the session (used as cookie name).
; http://php.net/session.name
session.name = PHPSESSID

session的过期时间

通过上面的介绍可以知道session共享的决定性因素是同一个session_id,而session_id是客户端存储的一个cookie,而cookie又可以设置过期时间,那么换种方式说:session其实也是可以设置过期时间的,本质是给session_id设置过期时间即可。

以下是php.ini中一段配置:

; Lifetime in seconds of cookie or, if 0, until browser is restarted.
; http://php.net/session.cookie-lifetime
session.cookie_lifetime = 0

可以看到session.cookie_lifetime默认为0,其实就是指session_id的cookie有效期直到下次浏览器重新打开,也就是该cookie属于session级别的,下次打开浏览器session_id是重新生成的,上次存储的所有session将不能访问。

image

如果想要设置session过期时间,本质其实是设置session_id的cookie有效期即可,只需要修改php.ini中参数session.cookie_lifetime值大于0即可。

在laravel中可以很方便的设置,不需要直接修改php.ini,只要修改session.php中的lifetime参数即可。

  'lifetime' => env('SESSION_LIFETIME', 120),

我们可以看到在laravel中session_id的cookie默认为laravel_session而不是下面的PHPSESSID,而且exprise设置了到期时间,不是session了。

session是和session_id关联的,不同的会话会产生不同的session_id,只有在同一sesssion_id的情况下,才会共享存储的session,不同session_id下存储的session是不能互相查询获取的。

Session在PHP中使用前必须开启session,函数是session_start()。在laravel可以放到web中间件里,web中间件实现了session_start()。

session驱动类型

cookie是存放在客户端的,而session是存放到服务器端的。看下面php.ini中的一段配置

; Handler used to store/retrieve data.
; http://php.net/session.save-handler
session.save_handler = files
; Argument passed to save_handler.  In the case of files, this is the path
; where data files are stored. Note: Windows users have to change this
; variable in order to use PHP's session functions.
;
; The path can be defined as:
;
;     session.save_path = "N;/path"

可以看出服务端的session数据默认是存储到file中的,其实session的驱动类型有如下几种

  • file : 默认选择方式。
  • database: Sessions 被存储在关系型数据库中
  • memcached / redis - Sessions 被存储在基于高速缓存的存储系统中。
  • cookie - Sessions 被存储在安全加密的 cookie 中。

在laravel中可以直接修改session.php文件中的环境变量SESSION_DRIVER来控制session使用哪种驱动。

比如我们使用来redis驱动,设置下面3个session

session(['mm'=>'aa']);
session(['kk'=>'bb']);
session(['cc'=>'ff']);

我们可以看看redis中是怎么存储这个3个数据的呢?

local:2>keys *
 1)  "laravel_cache:nOz7DwByMTrZWrDAf9zUhDzy9X6ApHLCu3iAhLjN"
local:2>get laravel_cache:nOz7DwByMTrZWrDAf9zUhDzy9X6ApHLCu3iAhLjN
"s:239:"a:6:{s:6:"_token";s:40:"XMKXtYmhu2gIwGDhCLUHDBJkCzFUBjKnsqPU0Vcs";s:2:"mm";s:2:"aa";s:2:"kk";s:2:"bb";s:2:"cc";s:2:"ff";s:9:"_previous";a:1:{s:3:"url";s:27:"http://127.0.0.1:8091/api/t";}s:6:"_flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}";"

可以看出该key为laravel_cache+session_id的格式,而且3个session的key value都存储在同一个key下,也就是说每个session_id会存储一个新key,该session_id下的所有session都存储在该key下,而不是多个key存储。

redis实现session的共享

由于系统用户的逐渐增多,我们通过使用负载均衡用户的访问流量,这时就会出现一个问题:
当用户A登录时,流量分发到后台集群的A节点,登录成功后session信息存储在A节点本地,当用户A刷新请求时,流量分发到了后台的集群B节点,由于此时B节点没有存储用户A的登录信息,所以又会提示用户A登录,这种现象对于用户体验是相当不好的,有以下俩种方式解决:

  1. 负载均衡器开启会话保持,负载均衡器将会将同一ip地址请求到同一个后台处理器。
  2. 使用redis做为session的驱动,后台所有服务器节点调用相同的redis。由于同一域名下的网站的cookie都是一样的,虽然调用不同的服务器节点,但是可以拿到相同的sesssion_id,也就可以避免上面出现的这种情况了。

session优点

  • session保存在服务端,安全性相对于cookie更好

session缺点

  • session同样时依附客户端的cookie,所以cookie的缺点同样是session的缺点。

session的使用方法

  • 增加session
$_SESSION['userId']=12
  • 删除session

unset() 函数用于释放指定的 session 变量:

 unset($_SESSION['views']);

session_destroy() 函数彻底销毁 session:

session_destroy();
  • 修改session
$_SESSION['userId']=12
  • 查询session
//查询所有的session
dd($_SESSION);
//查看单独的session
dd($_SESSION['userId'])

测试

  • chrome禁用cookie后,session能否使用
    1.写一个api
    public function index(Request $request)
    {
        session_start();
        $_SESSION['yy']=33333;
        echo $_SESSION['yy']."\n";
        echo session_id();
    }
  1. 访问该api,可以看到可以访问session yy。


    image

3.我们上面不是说的不能访问session了吗?经发现,不关闭浏览器的情况下,刷新页面后session_id是一直在变化的,也就是说,不能保持同一会话了。也就是说上次设置的session,在下次刷新页面后,session将不能访问。

  1. 为了验证上面的说法,重写api
   public function index(Request $request)
    {
        session_start();
        //$_SESSION['yy']=33333;
        echo $_SESSION['yy']."\n";
        echo session_id();
    }

5。 访问
在没禁用cookie的情况下。这里不关闭浏览器刷新页面的话是可以访问session yy的,因为session_id不会变,属于同一会话。

而此时我们刷新页面访问,应该session yy是不能访问的


image

和预想的一样

总结:把客户端的cookie禁用后,可以继续使用session,只是在不关闭浏览器的情况下不会保持同一会话了,也就是所有session都会消失。

Local Storage

localStorage 是 HTML5 标准中新加入的技术,它并不是什么划时代的新东西。早在 IE 6 时代,就有一个叫 userData 的东西用于本地存储,而当时考虑到浏览器兼容性,更通用的方案是使用 Flash。而如今,localStorage 被大多数浏览器所支持,如果你的网站需要支持 IE6+,那以 userData 作为你的 polyfill 的方案是种不错的选择。


image

Session Storage

sessionStorage 与 localStorage 的接口类似,但保存数据的生命周期与 localStorage 不同。做过后端开发的同学应该知道 Session 这个词的意思,直译过来是“会话”。而 sessionStorage 是一个前端的概念,它只是可以将一部分数据在当前会话中保存下来,刷新页面数据依旧存在。但当页面关闭后,sessionStorage 中的数据就会被清空。

我们后台的session是浏览器关闭后,session存储的消息不能共享,而Session Storage只要页面关闭后,session中的数据就会清空

cookie,Local Storage,Session Storage的对比

image

Local Storage,Session Storage两者的不同点在于:

1、生命周期 —— 数据可以存储多少时间

  • localStorage: 存储的数据是永久性的,除非用户人为删除否则会一直存在。
  • sessionStorage: 与存储数据的脚本所在的标签页的有效期是相同的。一旦窗口或者标签页被关闭,那么所有通过 sessionStorage 存储的数据也会被删除。

2、作用域 —— 谁拥有数据的访问权

  • localStorage: 在同一个浏览器内,同源文档之间共享 localStorage 数据,可以互相读取、覆盖。
  • sessionStorage: 与 localStorage 一样需要同一浏览器同源文档这一条件。不仅如此,sessionStorage 的作用域还被限定在了窗口中,也就是说,只有同一浏览器同一窗口的同源文档才能共享数据。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容