掃二維碼與項(xiàng)目經(jīng)理溝通
我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
什么是SESSION?

創(chuàng)新互聯(lián)公司網(wǎng)站建設(shè)服務(wù)商,為中小企業(yè)提供成都做網(wǎng)站、成都網(wǎng)站制作、成都外貿(mào)網(wǎng)站建設(shè)服務(wù),網(wǎng)站設(shè)計(jì),成都網(wǎng)站托管等一站式綜合服務(wù)型公司,專業(yè)打造企業(yè)形象網(wǎng)站,讓您在眾多競爭對手中脫穎而出創(chuàng)新互聯(lián)公司。
按照WIKI的解釋,SESSION是存在于兩個(gè)通信設(shè)備間的交互信息,在某一時(shí)間建立,經(jīng)過一定的時(shí)間后失效。常見的SESSION有:TCP SESSION、WEB SESSION(HTTP SESSION)、LOGIN SESSION等。
根據(jù)OSI模型中,會話實(shí)現(xiàn)的位置不同,SESSION主要分為幾種,一種是應(yīng)用層會話,包括WEB SESSION(HTTP SESSION)和telnet遠(yuǎn)程登錄session;會話層實(shí)現(xiàn)的,包括Session Initiation Protocol(SIP)和Internet Phone Call;在傳輸層實(shí)現(xiàn)的有TCP SESSION。
本文主要討論WEB SESSION,其一般有兩種:客戶端SESSION和服務(wù)器端SESSION,后一種最常見的屬于Java Beans提供的。
SESSION是做什么的?
在計(jì)算機(jī)領(lǐng)域,特別是網(wǎng)絡(luò)方面,SESSION使用的特別廣泛,也可以稱為是對話(Dialogue)、會話等,一般是指在兩個(gè)通信設(shè)備間存儲的狀態(tài),有時(shí)也發(fā)生在用戶和計(jì)算機(jī)之間(Login SESSION)。
區(qū)別于無狀態(tài)的通信,SESSION通常用來存儲通信狀態(tài),因此通信的雙方至少有一方需要存儲SESSION的歷史記錄,從而實(shí)現(xiàn)兩者間的通信。
SESSION(WEB SESSION)是怎么實(shí)現(xiàn)的?
瀏覽器和服務(wù)器之間進(jìn)行HTTP通信時(shí),通常會包含一個(gè) HTTP Cookie 來標(biāo)識狀態(tài),通常會有一個(gè)唯一的 SESSIONID ,SESSION通常記錄著用戶的一些驗(yàn)證信息和級別。
在幾中編程語言中最常用的Http Session Token是,JSESSIONID(JSP),PHPSESSID(PHP),ASPSESSIONID(ASP),這個(gè)標(biāo)識通常由哈希函數(shù)產(chǎn)生,能夠唯一表示這個(gè)用戶的身份,在服務(wù)器和客戶端通信時(shí),作為GET或者POST的參數(shù)存儲在客戶端。
SESSION的實(shí)現(xiàn)方式通常有兩種,服務(wù)器端SESSION和客戶端SESSION,兩種方式各有優(yōu)缺點(diǎn)。
服務(wù)器端SESSION實(shí)現(xiàn)容易并且效率比較高,但是遇到負(fù)載均衡或者高可用性需求的時(shí)候,處理起來就比較困難,對于那種內(nèi)生系統(tǒng)不存在存儲設(shè)備的時(shí)候,也是不可用的。負(fù)載均衡可以通過共享文件系統(tǒng)或者強(qiáng)制客戶只能登錄到一臺服務(wù)器上來實(shí)現(xiàn),但是這樣會降低效率。對于沒有存儲的設(shè)備,也可以通過使用RAM(參考參考資料6)來解決服務(wù)器端SESSION的實(shí)現(xiàn),這種方法這對哪些客戶端鏈接有限的系統(tǒng)有效(諸如路由或者接入點(diǎn)設(shè)備)。
客戶端SESSION的使用可以解決服務(wù)器端SESSION的一些問題,比如避免了負(fù)載均衡的算法等,但是同時(shí)也會產(chǎn)生一些自身的問題。客戶端SESSION使用Cookie和加密技術(shù)來在不同的請求間保存狀態(tài)。在每一個(gè)動(dòng)態(tài)頁面結(jié)束后,會統(tǒng)計(jì)當(dāng)前的SESSION,并把它發(fā)回客戶端。每次成功請求后,會把cookie再發(fā)送到服務(wù)器端,來讓服務(wù)器“記起”這個(gè)用戶的身份??蛻舳薙ESSION最重要的問題就是安全問題,一旦cookie被劫持或者篡改了,用戶的信息的安全性就喪失了。
PHP中如何設(shè)置SESSION?
搭建好PHP的開發(fā)環(huán)境后,通過phpinfo()可以查看到與SESSION有關(guān)的部分包括:
SESSION模塊,在PHP V5.2.9版本中,一共有25個(gè)變量。其中,平時(shí)設(shè)置中常會用到的幾個(gè)有:
session.cookie_lifetime 設(shè)置存儲SESSIONID的cookie過期時(shí)間
session.name SESSION的COOKIE名稱,默認(rèn)為PHPSESSID
session.save_handler SESSION的存儲方式,默認(rèn)為FILE
session.save_path Fedora下面默認(rèn)存儲在/var/lib/php/session
session.gc_probability
session.gc_divisor
session.gc_maxlifetime 這三個(gè)選項(xiàng)用來處理GC機(jī)制發(fā)生的機(jī)率
session.cache_limiter (nocache,private,private_no_expire,public)
session.cache_expire 這兩個(gè)選項(xiàng)是用來緩存SESSION的頁面
先來考慮***個(gè)問題,SESSION多久會過期,他是如何過期的?如果要在PHP程序中使用SESSION,一定要先引用session_start(),這個(gè)函數(shù)一執(zhí)行,就會在SESSION的存儲目錄(如果使用了file handler)生成一個(gè)SESSION文件,里面內(nèi)容是空的,同時(shí)瀏覽器會見里一個(gè)name為PHPSESSID的cookie,里面存儲著一個(gè)hash出來的SESSION的名字。
SESSION的過期依賴于一個(gè)垃圾回收機(jī)制(Garbage Collection),SESSION創(chuàng)建后作為一個(gè)文件存放在服務(wù)器上,客戶端腳本每訪問一次SESSION中的變量,SESSION文件的訪問時(shí)間就會進(jìn)行更新。每次訪問都是根據(jù)客戶端存儲的SESSIONID去請求服務(wù)器中存儲的唯一的SESSION,當(dāng)客戶端的cookie過期后,就無法知道要訪問的是哪一個(gè)SESSION,盡管此時(shí)服務(wù)器上的SESSION文件還沒有被過期收回,這樣就會造成服務(wù)器資源的浪費(fèi)。
但是同時(shí),如果我們希望用戶的session馬上過期的話,我們就可以通過設(shè)置cookie的辦法來實(shí)現(xiàn)。SESSION的回收是在每次訪問頁面的時(shí)候進(jìn)行的,回收的機(jī)率由session.gc_probability,session_gc_divisor指定,默認(rèn)士1/100。如果設(shè)置為1,則每次超過了SESSION的生存周期去訪問的話,SESSION一定會被回收。
兩種需求:1、PHP中保持SESSION不過期或延長SESSION過期時(shí)間;2、使SESSION立即過期。
1、PHP中保持SESSION不過期和延長SESSION過期時(shí)間非常必要,特別是在內(nèi)部應(yīng)用系統(tǒng)中或者有很大的表單的時(shí)候。想想你的老板在填寫一個(gè)表單,剛好碰上午飯時(shí)間,留著這個(gè)表單等吃飯回來,填寫完剩余的內(nèi)容,提交后他看到什么,一般來說都是一個(gè)登錄界面。想要提高用戶體驗(yàn),關(guān)鍵是要讓老板的表單不出問題,我們就必須延長SESSION的生存周期。
PHP中保持SESSION不過期和延長SESSION過期時(shí)間,可以通過設(shè)置session.gc_maxlifetime來實(shí)現(xiàn),不過首先需要保證客戶端的cookie不會在gc執(zhí)行回收之前失效。通過設(shè)置一個(gè)較長的gc_maxlifetime可以實(shí)現(xiàn)延長session的生存周期,可是對于不是所有請求都會保持很久的應(yīng)用來說,這么做對于服務(wù)器配置顯然不是一個(gè)***的選擇。
我們知道SESSION的回收機(jī)制是根據(jù)SESSION文件的***訪問時(shí)間來判斷的,如果超過了maxlifetime,則根據(jù)回收機(jī)率進(jìn)行回收。所以我們只需要定期的去訪問一下SESSION就可以了,而這可以通過刷新頁面來實(shí)現(xiàn),根據(jù)這個(gè)思路,解決的方法就有了。
通過JS定期的去訪問頁面;
利用Iframe定期的刷新頁面;
直接利用程序發(fā)送HTTP請求,這樣就可以避免在頁面中嵌入其他的元素;
下面是利用JS發(fā)送請求實(shí)現(xiàn)的保持SESSION不過期的實(shí)現(xiàn)方法,這樣我們就只需要在需要SESSION保持長時(shí)間的頁面(比如大表單頁面)。
其中URL后加入一個(gè)隨機(jī)數(shù)是為了避免這個(gè)鏈接的請求被瀏覽器緩存。
2、使SESSION立即過期的方法就比較多了,我們可以session_destroy(),也可以用上面的思路,請求一個(gè)session_destroy的頁面。
SESSION安全嗎?
PHP的手冊中明確寫出:SESSION并不能保證儲存在SESSION中的信息一定只能被他的創(chuàng)建者所看到。
如果想要安全的處理一些遠(yuǎn)程的操作,那么HTTPS是唯一的選擇。最基本的,不要認(rèn)為一個(gè)用戶信息在SESSION中存在就認(rèn)為這個(gè)用戶一定就是他本人,雖然SESSION中的信息會給你他已經(jīng)經(jīng)過了用戶名和密碼驗(yàn)證的假象。所以,如果需要做一些修改密碼或者類似的事情的時(shí)候,讓用戶重新輸入密碼是一個(gè)比較好的選擇。
早期的Apache版本并沒有采用COOKIE的方式來存儲PHPSESSID,而是采用的URL-rewrite,也就是每個(gè)URL后面都會加上PHPSESSID=
session.use_trans_id = 0;
所以從這個(gè)意義上來講,延長SESSION的時(shí)間過長或者保持SESSION一直在線對于安全來說始終不是一件好事情。***的解決辦法就是用戶提交跳轉(zhuǎn)到登錄窗口,登錄后又能夠回到填寫頁面,并且所有的數(shù)據(jù)都還在。這個(gè)的實(shí)現(xiàn)方式現(xiàn)在用Ajax來解決應(yīng)該沒什么困難,每隔一定時(shí)間就把當(dāng)前的用戶數(shù)據(jù)POST到一個(gè)存儲位置,不管是XML或者JSON。
PHP中保持SESSION拾遺:
對于客戶端不支持JavaScript的情況可以采用的方法:
1、寫一個(gè)浮層,顯示在最頂層,如果用戶未禁用JS,則讓浮層消失;
2、將所有的INPUT都設(shè)置為disable,然后再用JS設(shè)置為enabled;
以上這兩種方式都是在JS被禁用的時(shí)候,所有功能都不能用,如何在JS被禁用的情況下使我們的應(yīng)用仍然正常工作,這個(gè)貌似就比較困難。實(shí)現(xiàn)這個(gè)的所花的時(shí)間和所收到的效果大家要權(quán)衡一下。

我們在微信上24小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流