自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

如何在PHP中保持SESSION以及由此引發(fā)的一些思考

開(kāi)發(fā) 后端
最近的一個(gè)項(xiàng)目,里面有一個(gè)比較大的表單,用戶(hù)完成它需要很多時(shí)間,很多用戶(hù)花了千辛萬(wàn)苦完成之后,一提交發(fā)現(xiàn)SESSION過(guò)期,系統(tǒng)退出了,所以引起了研究如何設(shè)置SESSION以及PHP中保持SESSION在線的需要,下面是一些心得體會(huì)。

什么是SESSION?

按照WIKI的解釋?zhuān)琒ESSION是存在于兩個(gè)通信設(shè)備間的交互信息,在某一時(shí)間建立,經(jīng)過(guò)一定的時(shí)間后失效。常見(jiàn)的SESSION有:TCP SESSION、WEB SESSION(HTTP SESSION)、LOGIN SESSION等。

根據(jù)OSI模型中,會(huì)話實(shí)現(xiàn)的位置不同,SESSION主要分為幾種,一種是應(yīng)用層會(huì)話,包括WEB SESSION(HTTP SESSION)和telnet遠(yuǎn)程登錄session;會(huì)話層實(shí)現(xiàn)的,包括Session Initiation Protocol(SIP)和Internet Phone Call;在傳輸層實(shí)現(xiàn)的有TCP SESSION。

本文主要討論WEB SESSION,其一般有兩種:客戶(hù)端SESSION和服務(wù)器端SESSION,后一種最常見(jiàn)的屬于Java Beans提供的。

SESSION是做什么的?

在計(jì)算機(jī)領(lǐng)域,特別是網(wǎng)絡(luò)方面,SESSION使用的特別廣泛,也可以稱(chēng)為是對(duì)話(Dialogue)、會(huì)話等,一般是指在兩個(gè)通信設(shè)備間存儲(chǔ)的狀態(tài),有時(shí)也發(fā)生在用戶(hù)和計(jì)算機(jī)之間(Login SESSION)。

區(qū)別于無(wú)狀態(tài)的通信,SESSION通常用來(lái)存儲(chǔ)通信狀態(tài),因此通信的雙方至少有一方需要存儲(chǔ)SESSION的歷史記錄,從而實(shí)現(xiàn)兩者間的通信。

SESSION(WEB SESSION)是怎么實(shí)現(xiàn)的?

瀏覽器和服務(wù)器之間進(jìn)行HTTP通信時(shí),通常會(huì)包含一個(gè) HTTP Cookie 來(lái)標(biāo)識(shí)狀態(tài),通常會(huì)有一個(gè)唯一的 SESSIONID ,SESSION通常記錄著用戶(hù)的一些驗(yàn)證信息和級(jí)別。

在幾中編程語(yǔ)言中最常用的Http Session Token是,JSESSIONID(JSP),PHPSESSID(PHP),ASPSESSIONID(ASP),這個(gè)標(biāo)識(shí)通常由哈希函數(shù)產(chǎn)生,能夠唯一表示這個(gè)用戶(hù)的身份,在服務(wù)器和客戶(hù)端通信時(shí),作為GET或者POST的參數(shù)存儲(chǔ)在客戶(hù)端。

SESSION的實(shí)現(xiàn)方式通常有兩種,服務(wù)器端SESSION和客戶(hù)端SESSION,兩種方式各有優(yōu)缺點(diǎn)。

服務(wù)器端SESSION實(shí)現(xiàn)容易并且效率比較高,但是遇到負(fù)載均衡或者高可用性需求的時(shí)候,處理起來(lái)就比較困難,對(duì)于那種內(nèi)生系統(tǒng)不存在存儲(chǔ)設(shè)備的時(shí)候,也是不可用的。負(fù)載均衡可以通過(guò)共享文件系統(tǒng)或者強(qiáng)制客戶(hù)只能登錄到一臺(tái)服務(wù)器上來(lái)實(shí)現(xiàn),但是這樣會(huì)降低效率。對(duì)于沒(méi)有存儲(chǔ)的設(shè)備,也可以通過(guò)使用RAM(參考參考資料6)來(lái)解決服務(wù)器端SESSION的實(shí)現(xiàn),這種方法這對(duì)哪些客戶(hù)端鏈接有限的系統(tǒng)有效(諸如路由或者接入點(diǎn)設(shè)備)。

客戶(hù)端SESSION的使用可以解決服務(wù)器端SESSION的一些問(wèn)題,比如避免了負(fù)載均衡的算法等,但是同時(shí)也會(huì)產(chǎn)生一些自身的問(wèn)題??蛻?hù)端SESSION使用Cookie和加密技術(shù)來(lái)在不同的請(qǐng)求間保存狀態(tài)。在每一個(gè)動(dòng)態(tài)頁(yè)面結(jié)束后,會(huì)統(tǒng)計(jì)當(dāng)前的SESSION,并把它發(fā)回客戶(hù)端。每次成功請(qǐng)求后,會(huì)把cookie再發(fā)送到服務(wù)器端,來(lái)讓服務(wù)器“記起”這個(gè)用戶(hù)的身份??蛻?hù)端SESSION最重要的問(wèn)題就是安全問(wèn)題,一旦cookie被劫持或者篡改了,用戶(hù)的信息的安全性就喪失了。

PHP中如何設(shè)置SESSION?

搭建好PHP的開(kāi)發(fā)環(huán)境后,通過(guò)phpinfo()可以查看到與SESSION有關(guān)的部分包括:

SESSION模塊,在PHP V5.2.9版本中,一共有25個(gè)變量。其中,平時(shí)設(shè)置中常會(huì)用到的幾個(gè)有:

session.cookie_lifetime        設(shè)置存儲(chǔ)SESSIONID的cookie過(guò)期時(shí)間

session.name                SESSION的COOKIE名稱(chēng),默認(rèn)為PHPSESSID

session.save_handler        SESSION的存儲(chǔ)方式,默認(rèn)為FILE       

session.save_path            Fedora下面默認(rèn)存儲(chǔ)在/var/lib/php/session

session.gc_probability

session.gc_divisor

session.gc_maxlifetime        這三個(gè)選項(xiàng)用來(lái)處理GC機(jī)制發(fā)生的機(jī)率

session.cache_limiter    (nocache,private,private_no_expire,public)

session.cache_expire    這兩個(gè)選項(xiàng)是用來(lái)緩存SESSION的頁(yè)面

先來(lái)考慮***個(gè)問(wèn)題,SESSION多久會(huì)過(guò)期,他是如何過(guò)期的?如果要在PHP程序中使用SESSION,一定要先引用session_start(),這個(gè)函數(shù)一執(zhí)行,就會(huì)在SESSION的存儲(chǔ)目錄(如果使用了file handler)生成一個(gè)SESSION文件,里面內(nèi)容是空的,同時(shí)瀏覽器會(huì)見(jiàn)里一個(gè)name為PHPSESSID的cookie,里面存儲(chǔ)著一個(gè)hash出來(lái)的SESSION的名字。

SESSION的過(guò)期依賴(lài)于一個(gè)垃圾回收機(jī)制(Garbage Collection),SESSION創(chuàng)建后作為一個(gè)文件存放在服務(wù)器上,客戶(hù)端腳本每訪問(wèn)一次SESSION中的變量,SESSION文件的訪問(wèn)時(shí)間就會(huì)進(jìn)行更新。每次訪問(wèn)都是根據(jù)客戶(hù)端存儲(chǔ)的SESSIONID去請(qǐng)求服務(wù)器中存儲(chǔ)的唯一的SESSION,當(dāng)客戶(hù)端的cookie過(guò)期后,就無(wú)法知道要訪問(wèn)的是哪一個(gè)SESSION,盡管此時(shí)服務(wù)器上的SESSION文件還沒(méi)有被過(guò)期收回,這樣就會(huì)造成服務(wù)器資源的浪費(fèi)。

但是同時(shí),如果我們希望用戶(hù)的session馬上過(guò)期的話,我們就可以通過(guò)設(shè)置cookie的辦法來(lái)實(shí)現(xiàn)。SESSION的回收是在每次訪問(wèn)頁(yè)面的時(shí)候進(jìn)行的,回收的機(jī)率由session.gc_probability,session_gc_divisor指定,默認(rèn)士1/100。如果設(shè)置為1,則每次超過(guò)了SESSION的生存周期去訪問(wèn)的話,SESSION一定會(huì)被回收。

兩種需求:1、PHP中保持SESSION不過(guò)期或延長(zhǎng)SESSION過(guò)期時(shí)間;2、使SESSION立即過(guò)期。

1、PHP中保持SESSION不過(guò)期和延長(zhǎng)SESSION過(guò)期時(shí)間非常必要,特別是在內(nèi)部應(yīng)用系統(tǒng)中或者有很大的表單的時(shí)候。想想你的老板在填寫(xiě)一個(gè)表單,剛好碰上午飯時(shí)間,留著這個(gè)表單等吃飯回來(lái),填寫(xiě)完剩余的內(nèi)容,提交后他看到什么,一般來(lái)說(shuō)都是一個(gè)登錄界面。想要提高用戶(hù)體驗(yàn),關(guān)鍵是要讓老板的表單不出問(wèn)題,我們就必須延長(zhǎng)SESSION的生存周期。

PHP中保持SESSION不過(guò)期和延長(zhǎng)SESSION過(guò)期時(shí)間,可以通過(guò)設(shè)置session.gc_maxlifetime來(lái)實(shí)現(xiàn),不過(guò)首先需要保證客戶(hù)端的cookie不會(huì)在gc執(zhí)行回收之前失效。通過(guò)設(shè)置一個(gè)較長(zhǎng)的gc_maxlifetime可以實(shí)現(xiàn)延長(zhǎng)session的生存周期,可是對(duì)于不是所有請(qǐng)求都會(huì)保持很久的應(yīng)用來(lái)說(shuō),這么做對(duì)于服務(wù)器配置顯然不是一個(gè)***的選擇。

我們知道SESSION的回收機(jī)制是根據(jù)SESSION文件的***訪問(wèn)時(shí)間來(lái)判斷的,如果超過(guò)了maxlifetime,則根據(jù)回收機(jī)率進(jìn)行回收。所以我們只需要定期的去訪問(wèn)一下SESSION就可以了,而這可以通過(guò)刷新頁(yè)面來(lái)實(shí)現(xiàn),根據(jù)這個(gè)思路,解決的方法就有了。

通過(guò)JS定期的去訪問(wèn)頁(yè)面;

利用Iframe定期的刷新頁(yè)面;

直接利用程序發(fā)送HTTP請(qǐng)求,這樣就可以避免在頁(yè)面中嵌入其他的元素;

下面是利用JS發(fā)送請(qǐng)求實(shí)現(xiàn)的保持SESSION不過(guò)期的實(shí)現(xiàn)方法,這樣我們就只需要在需要SESSION保持長(zhǎng)時(shí)間的頁(yè)面(比如大表單頁(yè)面)。

   

  1. <script type="text/javascript">  
  2.         function keepMeAlive(imgName){  
  3.             myImg = document.getElementById(imgName);  
  4.             if(myImg) myImg.src = myImg.src.replace(/\?.*$/, '?' + Math.random());  
  5.         }  
  6.  
  7.         window.setInterval("keepMeAlive('phpImg');", 4000);  
  8.     </script>  
  9.     <img id="phpImg" src="http://www.phpplot.com/phpplot/session/sess_refresh.php?" width="1" height="1" /> 

其中URL后加入一個(gè)隨機(jī)數(shù)是為了避免這個(gè)鏈接的請(qǐng)求被瀏覽器緩存。

2、使SESSION立即過(guò)期的方法就比較多了,我們可以session_destroy(),也可以用上面的思路,請(qǐng)求一個(gè)session_destroy的頁(yè)面。

SESSION安全嗎?

PHP的手冊(cè)中明確寫(xiě)出:SESSION并不能保證儲(chǔ)存在SESSION中的信息一定只能被他的創(chuàng)建者所看到。

如果想要安全的處理一些遠(yuǎn)程的操作,那么HTTPS是唯一的選擇。最基本的,不要認(rèn)為一個(gè)用戶(hù)信息在SESSION中存在就認(rèn)為這個(gè)用戶(hù)一定就是他本人,雖然SESSION中的信息會(huì)給你他已經(jīng)經(jīng)過(guò)了用戶(hù)名和密碼驗(yàn)證的假象。所以,如果需要做一些修改密碼或者類(lèi)似的事情的時(shí)候,讓用戶(hù)重新輸入密碼是一個(gè)比較好的選擇。

早期的Apache版本并沒(méi)有采用COOKIE的方式來(lái)存儲(chǔ)PHPSESSID,而是采用的URL-rewrite,也就是每個(gè)URL后面都會(huì)加上PHPSESSID=<sessionid>來(lái)表明它屬于那個(gè)激活的SESSION,新版的Apache已經(jīng)將這個(gè)屬性設(shè)置為默認(rèn)關(guān)閉。

session.use_trans_id = 0;

所以從這個(gè)意義上來(lái)講,延長(zhǎng)SESSION的時(shí)間過(guò)長(zhǎng)或者保持SESSION一直在線對(duì)于安全來(lái)說(shuō)始終不是一件好事情。***的解決辦法就是用戶(hù)提交跳轉(zhuǎn)到登錄窗口,登錄后又能夠回到填寫(xiě)頁(yè)面,并且所有的數(shù)據(jù)都還在。這個(gè)的實(shí)現(xiàn)方式現(xiàn)在用Ajax來(lái)解決應(yīng)該沒(méi)什么困難,每隔一定時(shí)間就把當(dāng)前的用戶(hù)數(shù)據(jù)POST到一個(gè)存儲(chǔ)位置,不管是XML或者JSON。

PHP中保持SESSION拾遺:

對(duì)于客戶(hù)端不支持JavaScript的情況可以采用的方法:

1、寫(xiě)一個(gè)浮層,顯示在最頂層,如果用戶(hù)未禁用JS,則讓浮層消失;

2、將所有的INPUT都設(shè)置為disable,然后再用JS設(shè)置為enabled;

以上這兩種方式都是在JS被禁用的時(shí)候,所有功能都不能用,如何在JS被禁用的情況下使我們的應(yīng)用仍然正常工作,這個(gè)貌似就比較困難。實(shí)現(xiàn)這個(gè)的所花的時(shí)間和所收到的效果大家要權(quán)衡一下。

【編輯推薦】

  1. PHP 5中新增加日期(date)函數(shù)的常量簡(jiǎn)介
  2. 在PHP中如何判斷AJAX請(qǐng)求
  3. 如何書(shū)寫(xiě)安全的PHP代碼
  4. PHP5中的異常處理詳解
  5. 實(shí)戰(zhàn)PHP5+Apache2.2+MySQL5.1配置經(jīng)歷
責(zé)任編輯:彭凡 來(lái)源: cnblogs
相關(guān)推薦

2023-08-01 23:08:07

2021-06-06 16:15:57

地區(qū)接口項(xiàng)目

2020-02-03 16:03:36

疫情思考

2009-06-25 09:50:32

JSF

2011-11-30 15:57:18

2024-05-16 10:44:10

2009-06-18 13:42:48

Hibernate s

2017-09-01 12:48:34

DevSecOps安全運(yùn)維

2017-12-21 07:54:07

2019-09-17 09:21:01

2018-07-11 14:06:04

數(shù)據(jù)質(zhì)量數(shù)據(jù)治理數(shù)據(jù)清洗

2020-07-14 09:23:49

安全運(yùn)營(yíng)甲方乙方

2018-06-14 09:35:35

2021-06-10 10:02:19

優(yōu)化緩存性能

2011-08-01 10:37:29

軟件項(xiàng)目管理

2023-12-01 18:03:52

2021-01-14 23:24:38

incaseforma蠕蟲(chóng)病毒

2013-04-19 10:01:19

jQueryJS

2024-10-28 09:02:12

2018-07-23 12:03:01

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)