session详解

来源:互联网 发布:js修改parameter 编辑:程序博客网 时间:2024/06/05 17:46

原贴地址:https://www.tooto.cc/archives/178

 

session详解

发布于 2016-12-24   


会话工作流程
基础概念
session配置项
服务器对session的删除机制:
读取已过期的session会发生什么?
设置一个30分钟就过期的session
session安全
session函数

会话工作流程

当开始一个会话时,php会尝试从请求里查找会话id(通常从cookie里找),如果没找到,php就创建一个新的会话;会话开始后,php会把会话中的数据设置到$_SESSION变量中,当php结束时,又会自动读取$_SESSION变量中的数据,并把它发送给会话保存管理器进行存储。

基础概念

·        显式执行了session_start()或隐式开启了session(session.auto_start=1),就会生成会话文件(session文件),没有开启就不会生成。

·        会话id可以用存在客户端cookie,也可以用url参数传递,客户端通过会话id获取服务器的的会话数据。

·        任何客户端拿到会话id,都可以访问服务器的会话数据。

·        每一个会话都会创建一个session文件,如果把存session_id的cookie删掉,再访问又会重新创建一个session文件

·        unset($_SESSION['3'])只会删除文件内对应的数据,而session_destory()会删除sesssion文件,

·        php结束时,会话会关闭;也可以手动调用session_write_close()来关闭会话

·        开始会话后,php会给会话文件加锁,直到会话关闭,其他脚本才能再访问,高并发网站会引起其他页面阻塞,因此需要尽早调用session_write_close()来释放文件锁,或者换能支持并发的session处理器(session.save_handler),比如存redis

·        session(和所有已注册的变量)将被php内置的序列化方法在请求完成时序列化再保存,正因为会序列化,所以session不能存resource资源,也不能保存引用

·        session内容会保持key,value值,value类型

·        数据序列化方式session.serialize_handler默认值是php,最好改为php_serialize
原因是:数字索引或字符串索引包含了(|和!)不能被使用,不能写入session文件保存,也会导致脚本执行关闭时出现错误。以下都将无法保存,除非使用php_serialize
$_SESSION[2] = 2;
$_SESSION['3'] = '3';
$_SESSION['a|'] = '3';
$_SESSION['a!'] = '3';

·        过期的session,只要没有被删除,还是可以再访问到的。

session配置项

以下统一省略了session前缀

1.     .save_handler = files //存储方式

2.     .save_path = '/tmp' //存储目录;也可以='N;/path'='N;MODE;/path'

3.     N是目录深度,要用N必须先创建好目录,session自己不会创建目录;同时如果用了N并且N>0,自动回收就会失效

4.     MODE是权限,默认创建的文件权限是600

5.     .name = PHPSESSID //会话名,用cookie存session_id时cookie的key,只能由数字或字母组成

6.     .auto_start = 0 //是否在请求开始时自动启动一个会话

7.     .serialize_handler = php //序列化反序列化时用的处理器

8.     .gc_probalility = 1 //

9.     .gc_divisor = 100 //和上一个参数合起来用,此时表示1%,请求100次可以触发一次垃圾回收机制

10. .gc_maxlifetime = 1440 // 1440秒没有访问,就会被视为垃圾,如果设置了多级目录保存,可以手动清除session文件

11. find /path/to/sessions -cmin +24 -typef | xargs rm

12. .referer_check = '你的网址' //使用.use_trans_sid 时建议开启这个,只接受这个网址跳转的请求来获取会话数据;注意使用HTTPS , 浏览器将不会发送 referrer 请求头。

13. .use_strict_mode = 0 //开启时,会话模块只接受由它自己创建的会话id,不接受浏览器传递过来的未初始化的session_id;如果浏览器传来了,就返回一个新session_id;默认关闭,浏览器传了未初始化的,就直接用那个未初始化的session_id创建一个session文件。

14. .use_cookies = 1 //客户端使用cookie来存放session_id

15. .use_only_cookies = 1 //必须使用cookie来存放session_id,防止URL方式的攻击

16. .cookie_lifetime = 0 //保存session_id的cookie的生命周期,0是浏览器关闭就失效;该时间是相对于服务器的时间,和客户端浏览器可能不一样

17. .cookie_path='/' // cookie保存的路径,默认是/

18. .cookie_domain // cookie生效的域名,默认不设置

19. .cookie_secure=1 //是否只通过安全连接发送,在HTTPS时才生效

20. .cookie_httponly=1 //是否只能通过http协议来访问,开启后可以杜绝js来操作cookie,有效防止XSS攻击(不是所有浏览器都有效)

21.  

22. .hash_function=0 //生成session_id所用的算法,0表示md5(128位),1表示sha1(160位);从5.3开始可以使用更多的算法,查看hash_algos()方法的返回值可以获取所有可用的算法,这个参数除了是int也可以是string

23. .hash_bits_per_character=5 //允许用户定义将二进制散列数据转换为可读的格式时每个字符存放多少个比特。可能值为 '4'(0-9,a-f),'5'(0-9,a-v),以及 '6'(0-9,a-z,A-Z,"-",",")。至于是干啥的没搞懂。

24.  

25. .use_trans_sid=0 //是否启用URL传递session_id,如果用户cookie禁用,就自动在URL里传递;默认关闭

26. .url_rewriter.tags="a=href,area=href,frame=src,input=src,form=fakeentry" //启用URL传递时才生效,可以不理。指定在使用透明 SID 支持时哪些 HTML 标记会被修改以加入会话 ID

27.  

28. .cache_limiter=nocache 共有none/nocache/private/private_no_expire/public这些值可选,这和header控制那个页面缓存时间是一样的,一般不使用,[想看更多](http://php.net/manual/zh/function.session-cache-limiter.php)

29. .cache_expire=180 缓存时间秒数

30.  

31. .upload_progress.enabled=1/0 //是否开启文件上传进度追踪,开启后

32. .upload_progress.cleanup=1/0 //上传完毕后清理session

33. .upload_progress.prefix='' //设置key的前缀,会被包含在.upload_progress.name里;默认是"upload_progress_".

34. .upload_progress.name='' //和前缀一起使用,默认是"PHP_SESSION_UPLOAD_PROGRESS"。完整的key是$_SESSION[两个拼接起来]

35. .upload_progress.freq=1% //多久更新一次上传进度,可以是100字节,也可以是1%(默认值)

36. .upload_progress.min_freq=1 //两次进度更新的间隔,默认1

37. session.lazy_write=1 // php7新特性,开启后只有在session有变化时才写入

38. 更详细的看:http://php.net/manual/zh/session.upload-progress.php

39.  

40. .entropy_file = string 熵值文件

41. .entropy_length = int 从熵值文件里读的熵值长度字节数

session.use_cookies=1// 用cookie来传递sessionID
session.cookie_lifetime=3600 // cookie中保存sessionID的时间,默认为0,表示关闭浏览器就失效
session.gc_maxlifetime=3600 // session在服务器的保存时间,过了就会触发删除机制。

服务器对session的删除机制:

每一次会话请求会有一定的概率触发session回收机制,概率是session.gc_probability=1 除以session.gc_divisor = 100。
上面两个配置算的概率是1%,意思是每一次会话请求,会有1%的概率触发回收,删除所有不活跃时间达到session.gc_maxlifetime设置时间的session文件。不活跃时间用文件的最后修改时间计算。
另外:如果使用session.save_path设置session文件保存在其他地方,那么这个删除机制可能不会有效,就需要自己定时去删除了。

另外:
一台服务器如果有两个应用A和B,A应用设置session.gc_maxlifetime为10分钟,B应用设置为5分钟,那么5分钟到了就会把A的session也过期了,因为两个应用的session目录都是一个;解决这个问题就需要session.save_path把各自的应用设置到各自的目录里。

读取已过期的session会发生什么?

由于原理是先从session文件里读数据,然后有一定概率触发回收机制,然后再更新最后访问时间。
所以读取已经过期的session文件会发生:
1,被读取到,触发了回收机制把它删除,然后就读不到了。
2,被读取到,没有触发回收机制,更新了它的最后访问时间,它又回到有效期了。

设置一个30分钟就过期的session:

根据上面的内容可以看出,默认情况下,其实我们无法严格意义上的设置一个指定时间就不能访问的session,但在一般应用中,勉强可以用下面的方式来实现一个并不严格的:
0,session.use_cookies=1 // 用cookie来存会话id
1,session.cookie_lifetime = 1800 // session_id在客户端只保存30分钟,
2,session.gc_maxlifetime = 1800 // session文件在服务器端只保存30分钟。

如果一定要严格意思的设置过期,可以在代码里自己为每一个session值增加一个时间戳,每次访问前,判断时间戳。或者用redis等其他方式来存储session数据,redis的数据到期之后就不能再get到。

session安全

为了尽可能提高session的安全性,可以做如下设置:
session.cookie_lifetime=0; // 浏览器关闭会话id就销毁
session.use_cookies=on; // 用cookie传递会话id
session.use_only_cookies=on; // 只用cookie传递会话id而不是url
session.use_strict_mode=On; // 让会话管理器只接受由自己创建的会话id
session.cookie_httponly=on; // 禁止 JavaScript 访问会话 cookie
session.cookie_secure=On; // 只允许在https协议下访问cookie存的session_id
session.hash_function = "sha256" // 生成更高强度的session_id

session函数

查看全部session函数

 

0 0
原创粉丝点击