亚洲精品中文字幕无乱码_久久亚洲精品无码AV大片_最新国产免费Av网址_国产精品3级片

php語(yǔ)言

PHP中使用會(huì)話控制

時(shí)間:2023-11-21 22:40:08 曉麗 php語(yǔ)言 我要投稿
  • 相關(guān)推薦

PHP中使用會(huì)話控制

  會(huì)話控制的思想是指能夠在網(wǎng)站中根據(jù)一個(gè)會(huì)話跟蹤用戶,下面是小編整理的PHP中使用會(huì)話控制,希望大家喜歡。

  PHP中使用會(huì)話控制

  1、什么是會(huì)話控制

  HTTP是一種無(wú)狀態(tài)協(xié)議,它的內(nèi)部沒(méi)有一個(gè)內(nèi)建機(jī)制來(lái)維護(hù)兩個(gè)事務(wù)之間的狀態(tài)。當(dāng)一個(gè)用戶在請(qǐng)求一個(gè)頁(yè)面后再請(qǐng)求另一個(gè)頁(yè)面,HTTP將無(wú)法告訴我們這兩個(gè)請(qǐng)求時(shí)來(lái)自同一個(gè)用戶。

  會(huì)話控制的思想是指能夠在網(wǎng)站中根據(jù)一個(gè)會(huì)話跟蹤用戶,這樣可以很容易的做到對(duì)用戶登錄的支持,并根據(jù)其授權(quán)級(jí)別和個(gè)人喜好顯示相應(yīng)的內(nèi)容,我們可以根據(jù)會(huì)話控制記錄該用戶行為,還可以實(shí)現(xiàn)購(gòu)物車(chē)。

  2、理解基本的會(huì)話功能

  PHP的會(huì)話是通過(guò)唯一的會(huì)話ID來(lái)驅(qū)動(dòng)的,會(huì)話ID是一個(gè)加密的隨機(jī)數(shù)字。它由PHP生成,在會(huì)話的生命周期中會(huì)保存在客戶端,它可以保存在用戶機(jī)器里的cookie中,或者通過(guò)URL在網(wǎng)絡(luò)上傳遞。

  會(huì)話ID就像一把鑰匙,它允許我們注冊(cè)一些特定的變量,也成為會(huì)話變量。這些變量的內(nèi)容會(huì)保存在服務(wù)器端。會(huì)話ID是客戶端唯一可見(jiàn)信息。如果在一次特定的網(wǎng)站鏈接中,客戶端可以通過(guò)cookie或URL看到會(huì)話ID,那么我們就可以訪問(wèn)該會(huì)話保存在服務(wù)器中的會(huì)話變量。在默認(rèn)情況下,會(huì)話變量保存在服務(wù)器上的普通文件中。

  把會(huì)話ID保存在URL中,如果在URL中有一串看起來(lái)像隨機(jī)數(shù)字的字符串,可能它就是某種形式的會(huì)話控制。

  cookie是與會(huì)話不同的解決方案,它也解決了在多個(gè)事務(wù)之間保持狀態(tài)的問(wèn)題,同時(shí)還可以保持一個(gè)整潔的URL。

  會(huì)話控制過(guò)程:用戶登錄或者第一次瀏覽某個(gè)站點(diǎn)的頁(yè)面時(shí),該站點(diǎn)會(huì)生成一個(gè)PHP的會(huì)話ID并通過(guò)cookie發(fā)送到客戶端(瀏覽器)。當(dāng)用戶點(diǎn)擊該站點(diǎn)的另一個(gè)頁(yè)面時(shí),瀏覽器開(kāi)始連接這個(gè)URL。在連接之前,瀏覽器會(huì)先搜索本地保存的cookie,如果在cookie中有任何與正在連接的URL相關(guān)的cookie,就將它提交到服務(wù)器。而剛好在登陸或第一次連接時(shí),已經(jīng)產(chǎn)生了一個(gè)與該網(wǎng)站URL相關(guān)的cookie(保存的會(huì)話ID),所以當(dāng)用戶再次連接這個(gè)站點(diǎn)時(shí),站點(diǎn)就可以通過(guò)這個(gè)會(huì)話ID識(shí)別出用戶,從服務(wù)器的會(huì)話文件中取出與這個(gè)會(huì)話ID相關(guān)的會(huì)話變量,從而保持事務(wù)之間的連續(xù)。

  3、什么是Cookie

  cookie是在服務(wù)器端被創(chuàng)建并寫(xiě)回到客戶端瀏覽器,瀏覽器接到響應(yīng)頭中關(guān)于寫(xiě)cookie的指令則在本地臨時(shí)文件夾中。創(chuàng)建了一個(gè)cookie文件,其中保存了你的cookie內(nèi)容,cookie內(nèi)容的存儲(chǔ)是鍵值對(duì)的方式,鍵和值都只能是字符串。

  cookie其實(shí)就是一小段信息,它可以由腳本在客戶端機(jī)器保存?梢酝ㄟ^(guò)發(fā)送一個(gè)包含特定數(shù)據(jù)并且具有如下格式的HTTP標(biāo)題頭,從而在用戶端機(jī)器設(shè)置一個(gè)cookie:

  Set-Cookie:NAME = VALUE; [expires=DATE;] [path=PATH;] [domain=DOAMIN_NAME;] [secure]

  這會(huì)創(chuàng)建一個(gè)名為NAME,值為VALUE的cookie。除了該參數(shù),其它參數(shù)都是可選的。expires域設(shè)置該cookie的失效日期(如果不設(shè)置失效日期將永遠(yuǎn)有效,除非手動(dòng)刪除)。path和domain域結(jié)合起來(lái)制定URL或與cookie有關(guān)的URL。secure的關(guān)鍵字的意思是在普通的HTTP連接中不發(fā)動(dòng)cookie。

  當(dāng)瀏覽器連接一個(gè)URL時(shí),首先要搜索當(dāng)?shù)乇4娴腸ookie。如果有任何與正在連接的URL相關(guān)的cookie,瀏覽器將它提交到服務(wù)器。

  4、什么是Session

  Session是由應(yīng)用服務(wù)器維持的一個(gè)服務(wù)器端的存儲(chǔ)空間,用戶在連接服務(wù)器時(shí),會(huì)由服務(wù)器創(chuàng)建生成一個(gè)唯一的sessionID,用該sessionID為標(biāo)識(shí)符來(lái)存取服務(wù)器端的Session存儲(chǔ)空間,在會(huì)話期間,分配給客戶端的唯一sessionID,用來(lái)標(biāo)識(shí)當(dāng)前用戶,與其他用戶進(jìn)行區(qū)分。通過(guò)SessionID接受每一次訪問(wèn)的請(qǐng)求,從而識(shí)別當(dāng)前用戶,跟蹤和保持用戶的具體資料,以及session變量,可在session中存儲(chǔ)數(shù)字或文字資料.比如session_name.這些信息都保存在服務(wù)器端。當(dāng)然,sessionID也可以作為會(huì)話信息保存到數(shù)據(jù)庫(kù)中,進(jìn)行session持久化。這樣可以跟蹤用戶的登陸次數(shù)、在線與否、在線時(shí)間等從而維護(hù)HTTP無(wú)狀態(tài)事物之間的關(guān)系。session的內(nèi)容存儲(chǔ)是鍵值對(duì)的列表,鍵是字符串類(lèi)型,session的存儲(chǔ)更方便,值可以是對(duì)象。

  在session會(huì)話期間,session會(huì)分別保存在客戶端和服務(wù)器端兩個(gè)文件,客戶端可以是cookie方式保存的sessionID(默認(rèn)的保存方式)或通過(guò)url字符串形式傳遞。服務(wù)器端一般以文本的形式保存在指定的session目錄中。在服務(wù)器端我們可以通過(guò)session.use_cookies來(lái)控制客戶端使用哪一種保存方式。如果定義為cookie保存方式,我們可以通過(guò)session.cookie_lifetime(默認(rèn)值0,閉瀏覽器就清除)來(lái)控制被保存在client上的cookie的有效期。而如果客戶端用cookie方式保存的sessionID,則使用“臨時(shí)”的cookie保存(cookie的名稱為PHPSESSID,通過(guò)Firebug你可以了解到詳細(xì)的信息,該名稱你可以通過(guò)php.ini session.name進(jìn)行更改),用戶提交頁(yè)面時(shí),會(huì)將這一SessionID提交到服務(wù)器端,來(lái)存取session數(shù)據(jù)。這一過(guò)程,是不用開(kāi)發(fā)人員干預(yù)的。

  5、SESSION和COOKIE的區(qū)別與聯(lián)系

  相同點(diǎn):都可以在解決HTTP無(wú)狀態(tài)的問(wèn)題,使同一個(gè)客戶端在訪問(wèn)網(wǎng)站的多次請(qǐng)求中,可以保存,設(shè)置信息,并且在請(qǐng)求事物之間建立聯(lián)系。

  不同點(diǎn):簡(jiǎn)單的說(shuō)cookie的信息保存在客戶端,session的信息保存在服務(wù)器端。

  Session采用鍵值對(duì),也就是說(shuō)ID存放客戶端,而值放在服務(wù)器端,是通過(guò)用戶的ID去找服務(wù)器上對(duì)應(yīng)的值,這種方式值放置在服務(wù)器端,有個(gè)時(shí)間限制,時(shí)間到則服務(wù)器自動(dòng)回收/釋放。

  Cookies則有兩種方法,一種方法是把值保存在瀏覽器的變量中,當(dāng)瀏覽器關(guān)閉時(shí)結(jié)束,另一種方法是保存在硬盤(pán)中,只要時(shí)間不過(guò)期,下次還可使用。

  聯(lián)系:當(dāng)客戶端使用基于Cookie方式保存的SessionID時(shí),SessionID一般保存在cookie中。

  備注:cookie在相同內(nèi)核的瀏覽器之間是共享的,不同內(nèi)核瀏覽器是不共享的例如火狐和IE(存放位置都不同,當(dāng)然不共享)。不同內(nèi)核瀏覽器不能共享cookie,也會(huì)產(chǎn)生不同sessionid。

  PHP中使用會(huì)話控制

  會(huì)話管理基礎(chǔ)

  會(huì)話安全

  會(huì)話模塊無(wú)法保證你存儲(chǔ)在會(huì)話中的信息只能被創(chuàng)建會(huì)話的用戶本人可見(jiàn)。 你需要采取額外的手段來(lái)保護(hù)會(huì)話中的機(jī)密信息, 至于采取何種方式來(lái)保護(hù)機(jī)密信息, 取決于你在會(huì)話中存儲(chǔ)的數(shù)據(jù)的機(jī)密程度。

  評(píng)估會(huì)話中存儲(chǔ)的數(shù)據(jù)的重要性, 以及為此增加額外的保護(hù)機(jī)制, 通常需要付出一定的代價(jià),同時(shí)會(huì)降低便利性。 例如,如果你需要保護(hù)用戶免受社會(huì)工程學(xué)攻擊, 你需要啟用session.use_only_cookies選項(xiàng)。 這就要求用戶在使用過(guò)程中,必須把瀏覽器設(shè)置為接受 cookie, 否則就無(wú)法正常使用會(huì)話功能了。

  有很多種方式都可以導(dǎo)致會(huì)話 ID 被泄露給第三方。 例如,JavaScript 注入,URL 中包含會(huì)話 ID,數(shù)據(jù)包偵聽(tīng), 或者直接訪問(wèn)你的物理設(shè)備等。 如果會(huì)話 ID 被泄漏給第三方, 那么他們就可以訪問(wèn)這個(gè)會(huì)話 ID 可以訪問(wèn)的全部資源。 首先,如果在 URL 中包含了會(huì)話 ID, 并且訪問(wèn)了外部的站點(diǎn), 那么你的會(huì)話 ID 可能在外部站點(diǎn)的訪問(wèn)日志中被記錄(referrer 請(qǐng)求頭)。 另外,攻擊者也可以監(jiān)聽(tīng)你的網(wǎng)絡(luò)通信,如果通信未加密, 那么會(huì)話 ID 將會(huì)在網(wǎng)絡(luò)中以明文的形式進(jìn)行傳輸。 針對(duì)這種情況的解決方案就是在服務(wù)端配置 SSL/TLS, 另外,使用 HSTS 可以達(dá)到更高的安全性。

  注意:即使使用 HTTPS 協(xié)議,也無(wú)法百分百保證機(jī)密數(shù)據(jù)不被泄漏。 例如,CRIME 和 BEAST 漏洞可以使得攻擊者讀取到你的數(shù)據(jù)。 另外,出于網(wǎng)絡(luò)通信審計(jì)目的,很多網(wǎng)絡(luò)中都存在 HTTPS MITM 代理, 可以讀取 HTTPS 協(xié)議下的通信數(shù)據(jù)。 那么攻擊者也可以搭建類(lèi)似的代理服務(wù)器,用來(lái)竊取 HTTPS 協(xié)議下的通信數(shù)據(jù)。

  非自適應(yīng)會(huì)話管理

  目前,默認(rèn)情況下,PHP 是以自適應(yīng)的方式來(lái)管理會(huì)話的, 這種方式使用起來(lái)很靈活,但是同樣也帶來(lái)了一定的風(fēng)險(xiǎn)。

  新增加了一個(gè)配置項(xiàng):session.use_strict_mode。 當(dāng)啟用這個(gè)配置項(xiàng),并且你所用的會(huì)話存儲(chǔ)處理器支持的話,未經(jīng)初始化的會(huì)話 ID 會(huì)被拒絕, 并為其生成一個(gè)全新的會(huì)話,這可以避免攻擊者使用一個(gè)已知的會(huì)話 ID 來(lái)進(jìn)行攻擊。 例如,攻擊者可以通過(guò)郵件給受害者發(fā)送一個(gè)包含會(huì)話ID 的鏈接: http://example.com/page.php?PHPSESSID=123456789。 如果啟用了session.use_trans_sid配置項(xiàng), 那么受害者將會(huì)使用攻擊者所提供的會(huì)話 ID 開(kāi)始一個(gè)新的會(huì)話。 如果啟用了session.use_strict_mode選項(xiàng),就可以降低風(fēng)險(xiǎn)。

  警告

  用戶自定義的會(huì)話存儲(chǔ)器也可以通過(guò)實(shí)現(xiàn)會(huì)話 ID 驗(yàn)證來(lái)支持嚴(yán)格會(huì)話模式。 建議用戶在實(shí)現(xiàn)自己的會(huì)話存儲(chǔ)器的時(shí)候, 一定要對(duì)會(huì)話 ID 的合法性進(jìn)行驗(yàn)證。

  在瀏覽器一側(cè),可以為用來(lái)保存會(huì)話 ID 的 cookie 設(shè)置域,路徑, 僅允許 HTTP 訪問(wèn),必須使用 HTTPS 訪問(wèn)等安全屬性。 如果使用的是 PHP 7.3. 版本,還可以對(duì) cookie 設(shè)置 SameSite 屬性。 攻擊者可以利用瀏覽器的這些特性來(lái)設(shè)置永久可用的會(huì)話 ID。 僅僅設(shè)置session.use_only_cookies配置項(xiàng) 無(wú)法解決這個(gè)問(wèn)題。而session.use_strict_mode配置項(xiàng) 可以降低這種風(fēng)險(xiǎn)。設(shè)置session.use_strict_mode=On, 來(lái)拒絕未經(jīng)初始化的會(huì)話 ID。

  注意:雖然使用session.use_strict_mode配置項(xiàng) 可以降低靈活會(huì)話管理方式所帶來(lái)的風(fēng)險(xiǎn), 攻擊者還是通過(guò)利用 JavaScript 注入等手段, 強(qiáng)制用戶使用由攻擊者創(chuàng)建的并且經(jīng)過(guò)了正常的初始化的會(huì)話 ID。 如何降低這種風(fēng)向,可以參考本手冊(cè)的建議部分。如果你已經(jīng)啟用了session.use_strict_mode配置項(xiàng), 同時(shí)使用基于時(shí)間戳的會(huì)話管理, 并且通過(guò)設(shè)置session_regenerate_id()配置項(xiàng) 來(lái)重新生成會(huì)話 ID, 那么,攻擊者生成的會(huì)話 ID 就可以被刪除掉了。當(dāng)發(fā)生對(duì)過(guò)期會(huì)話訪問(wèn)的時(shí)候, 你應(yīng)該保存活躍會(huì)話的所有數(shù)據(jù), 以備后續(xù)分析使用。 然后讓用戶退出當(dāng)前的會(huì)話,并且重新登錄。 防止攻擊者繼續(xù)使用“偷”來(lái)的會(huì)話。

  警告

  對(duì)過(guò)期會(huì)話數(shù)據(jù)的訪問(wèn)并不總是意味著正在遭受攻擊。 不穩(wěn)定的網(wǎng)絡(luò)狀況,或者不正確的會(huì)話刪除行為, 都會(huì)導(dǎo)致合法的用戶產(chǎn)生訪問(wèn)過(guò)期會(huì)話數(shù)據(jù)的情況。

  從 PHP 7.1.0 開(kāi)始,增加了session_create_id()函數(shù)。 這個(gè)函數(shù)允許開(kāi)發(fā)者在會(huì)話 ID 中增加用戶 ID 作為前綴, 以確保用戶訪問(wèn)到正確對(duì)應(yīng)的會(huì)話數(shù)據(jù)。 要使用這個(gè)函數(shù), 請(qǐng)確保啟用了session.use_strict_mode配置項(xiàng), 否則惡意用戶可能會(huì)偽造其他用戶的會(huì)話 ID。

  注意:對(duì)于 PHP 7.1.0 之前的用戶,應(yīng)該使用CSPRNG(例如/dev/urandom) 或者random_bytes()函數(shù)以及哈希函數(shù) 來(lái)產(chǎn)生新的會(huì)話 ID。session_create_id()函數(shù)本身包含碰撞檢測(cè)的能力, 并且根據(jù) INI 文件中和會(huì)話相關(guān)的配置項(xiàng)來(lái)生成會(huì)話 ID。 所以,建議使用session_create_id()函數(shù)來(lái)生成會(huì)話 ID。

  重新生成會(huì)話 ID

  雖然session.use_strict_mode配置項(xiàng)可以降低風(fēng)險(xiǎn),但是還不夠。為了確保會(huì)話安全,開(kāi)發(fā)者還需要使用session_regenerate_id()函數(shù)。

  會(huì)話 ID 重生機(jī)制可以有效的降低會(huì)話被竊取的風(fēng)險(xiǎn), 所以,必須周期性的調(diào)用session_regenerate_id()函數(shù) 來(lái)重新生成會(huì)話 ID, 例如,對(duì)于機(jī)密內(nèi)容,每隔 15 分鐘就重新生成會(huì)話 ID。 這樣一來(lái),即使會(huì)話 ID 被竊取, 那么攻擊者所得到的會(huì)話 ID 也會(huì)很快的過(guò)期, 如果他們進(jìn)一步訪問(wèn),就會(huì)產(chǎn)生對(duì)過(guò)期會(huì)話數(shù)據(jù)訪問(wèn)的錯(cuò)誤。

  當(dāng)用戶成功通過(guò)認(rèn)證之后,必須為其重新生成會(huì)話 ID。 并且,必須在向$_SESSION中保存用戶認(rèn)證信息之前 調(diào)用session_regenerate_id()函數(shù)(session_regenerate_id()函數(shù) 會(huì)自動(dòng)將重生之前的會(huì)話數(shù)據(jù)保存到新生成的會(huì)話)。 請(qǐng)確保只有新的會(huì)話包含用戶認(rèn)證信息。

  開(kāi)發(fā)者不可過(guò)分依賴session.gc_maxlifetime配置項(xiàng)。 因?yàn)楣粽呖梢栽谑芎φ叩臅?huì)話過(guò)期之前訪問(wèn)系統(tǒng), 并且維持這個(gè)會(huì)話的活動(dòng),以保證這個(gè)會(huì)話不會(huì)過(guò)期。

  實(shí)際上,你需要自己實(shí)現(xiàn)基于時(shí)間戳的會(huì)話數(shù)據(jù)管理機(jī)制。

  警告

  雖然會(huì)話處理程序可以透明的管理時(shí)間戳,但是這個(gè)特性尚未完整的實(shí)現(xiàn)。 在 GC 發(fā)生之前,舊的會(huì)話數(shù)據(jù)還得保存, 同時(shí),開(kāi)發(fā)者還得保證過(guò)期的會(huì)話數(shù)據(jù)已經(jīng)被移除。 但是,開(kāi)發(fā)者又不能立即移除活躍會(huì)話中的數(shù)據(jù)。 所以,不要同時(shí)在活躍會(huì)話上調(diào)用session_regenerate_id(true);和session_destroy()函數(shù)。 這聽(tīng)起來(lái)有點(diǎn)兒自相矛盾,但是事實(shí)上必須得這么做。

  默認(rèn)情況下,session_regenerate_id()函數(shù)不會(huì)刪除舊的會(huì)話, 所以即使重生了會(huì)話 ID,舊的會(huì)話可能還是可用的。 開(kāi)發(fā)者需要使用時(shí)間戳等機(jī)制, 來(lái)確保舊的會(huì)話數(shù)據(jù)不會(huì)再次被訪問(wèn)。

  警告

  刪除活躍會(huì)話可能會(huì)帶來(lái)非預(yù)期的一些影響。 例如,在網(wǎng)絡(luò)狀態(tài)不穩(wěn)定,或者有并發(fā)請(qǐng)求到達(dá) Web 服務(wù)器的情況下, 立即刪除活躍會(huì)話可能導(dǎo)致個(gè)別請(qǐng)求會(huì)話失效的問(wèn)題。

  立即刪除活躍會(huì)話也無(wú)法檢測(cè)可能存在的惡意訪問(wèn)。

  作為替代方案, 你要在$_SESSION中設(shè)置一個(gè)很短的過(guò)期時(shí)間, 然后根據(jù)這個(gè)時(shí)間戳來(lái)判斷后續(xù)的訪問(wèn)是被允許的還是被禁止的。

  在調(diào)用session_regenerate_id()函數(shù)之后, 不能立即禁止對(duì)舊的會(huì)話數(shù)據(jù)的訪問(wèn),應(yīng)該再一小段之間之后再禁止訪問(wèn)。 例如,在穩(wěn)定的網(wǎng)絡(luò)條件下,可以設(shè)置為幾秒鐘, 在不穩(wěn)定的網(wǎng)絡(luò)條件下,可以設(shè)置為幾分鐘。

  如果用戶訪問(wèn)了舊的會(huì)話數(shù)據(jù)(已經(jīng)過(guò)期的), 那么應(yīng)該禁止訪問(wèn)。 建議從會(huì)話中移除這個(gè)用戶的認(rèn)證信息,因?yàn)檫@看起來(lái)像是在遭受攻擊。

  如果攻擊者設(shè)置了不可刪除的 cookie,那么使用session.use_only_cookies和session_regenerate_id()會(huì)導(dǎo)致正常用戶遭受拒絕服務(wù)的問(wèn)題。 如果發(fā)生這種情況,請(qǐng)讓用戶刪除 cookie 并且警告用戶他可能面臨一些安全問(wèn)題。 攻擊者可以通過(guò)惡意的 Web 應(yīng)用、瀏覽器插件以及對(duì)安全性較差的物理設(shè)備進(jìn)行攻擊 來(lái)偽造惡意的 cookie。

  警告

  請(qǐng)勿誤解這里的拒絕服務(wù)攻擊風(fēng)險(xiǎn)所指的含義。 通常來(lái)講,要保護(hù)會(huì)話 ID 的安全,session.use_strict_mode=On 是必須要做的。 建議所有的站點(diǎn)都啟用session.use_strict_mode。

  只有當(dāng)賬號(hào)處于被攻擊的時(shí)候,才會(huì)發(fā)生拒絕服務(wù)的問(wèn)題。 通常都是由于應(yīng)用中被注入了惡意的 JavaScript 才會(huì)導(dǎo)致這個(gè)問(wèn)題。

  會(huì)話中數(shù)據(jù)的刪除

  過(guò)期的會(huì)話中的數(shù)據(jù)應(yīng)該是被刪除的,并且不可訪問(wèn)。 現(xiàn)在的會(huì)話模塊尚未很好的支持這種特性。

  應(yīng)該盡可能快的刪除過(guò)期會(huì)話中的數(shù)據(jù)。 但是,活躍會(huì)話一定不要立即刪除。 為了能夠同時(shí)滿足這兩點(diǎn)要求, 你需要自己來(lái)實(shí)現(xiàn)基于時(shí)間戳的會(huì)話數(shù)據(jù)管理機(jī)制。

  在 $_SESSION 中設(shè)置會(huì)話過(guò)期時(shí)間戳,并且對(duì)其進(jìn)行管理, 以便能夠阻止對(duì)于過(guò)期會(huì)話的訪問(wèn)。 當(dāng)發(fā)生對(duì)于過(guò)期會(huì)話的訪問(wèn)時(shí),建議從相關(guān)用戶的所有會(huì)話中刪除認(rèn)證信息, 并且要求用戶重新認(rèn)證。 對(duì)于過(guò)期會(huì)話數(shù)據(jù)的訪問(wèn)可能是一種攻擊行為, 為了保護(hù)會(huì)話數(shù)據(jù),你需要追蹤每個(gè)用戶的活躍會(huì)話。

  注意:當(dāng)用戶處于不穩(wěn)定的網(wǎng)絡(luò),或者 web 應(yīng)用存在并發(fā)的請(qǐng)求的時(shí)候, 也可能發(fā)生對(duì)于過(guò)期會(huì)話數(shù)據(jù)的訪問(wèn)。 服務(wù)器嘗試為用戶設(shè)置新的會(huì)話 ID, 但是很可能由于網(wǎng)絡(luò)原因,導(dǎo)致 Set-Cookie 的數(shù)據(jù)包無(wú)法到達(dá)用戶的瀏覽器。 當(dāng)通過(guò)session_regenerate_id()函數(shù) 為一個(gè)連接生成新的會(huì)話 ID 之后,其他的并發(fā)連接可能尚未得到這個(gè)新的會(huì)話 ID。 因此,不能立即阻止對(duì)于過(guò)期會(huì)話數(shù)據(jù)的訪問(wèn),而是要延遲一個(gè)很小的時(shí)間段, 這就是為什么我們需要實(shí)現(xiàn)基于時(shí)間戳的會(huì)話管理。

  簡(jiǎn)而言之,不要在調(diào)用session_regenerate_id()或者session_destroy()函數(shù)的時(shí)候立即刪除舊的會(huì)話數(shù)據(jù), 而是要通過(guò)一個(gè)時(shí)間戳來(lái)控制后續(xù)對(duì)于這個(gè)舊會(huì)話數(shù)據(jù)的訪問(wèn)。 從會(huì)話存儲(chǔ)中刪除數(shù)據(jù)的工作交給session_gc()函數(shù)來(lái)完成吧。

  會(huì)話和鎖定

  默認(rèn)情況下,為了保證會(huì)話數(shù)據(jù)在多個(gè)請(qǐng)求之間的一致性, 對(duì)于會(huì)話數(shù)據(jù)的訪問(wèn)是加鎖進(jìn)行的。

  但是,這種鎖定機(jī)制也會(huì)導(dǎo)致被攻擊者利用,來(lái)進(jìn)行對(duì)于用戶的拒絕服務(wù)攻擊。 為了降低這種風(fēng)險(xiǎn),請(qǐng)?jiān)谠L問(wèn)會(huì)話數(shù)據(jù)的時(shí)候,盡可能的縮短鎖定的時(shí)間。 當(dāng)某個(gè)請(qǐng)求不需要更新會(huì)話數(shù)據(jù)的時(shí)候,使用只讀模式訪問(wèn)會(huì)話數(shù)據(jù)。 也就是說(shuō),在調(diào)用session_start()函數(shù)的時(shí)候, 使用 read_and_close 選項(xiàng):session_start([read_and_close=>1]);。 另外,如果需要更新會(huì)話數(shù)據(jù),那么在更新完畢之后, 馬上調(diào)用session_commit()函數(shù)來(lái)釋放對(duì)于會(huì)話數(shù)據(jù)的鎖。

  當(dāng)會(huì)話不活躍的時(shí)候,當(dāng)前的會(huì)話模塊不會(huì)檢測(cè)對(duì)于 $_SESSION 的修改。 你需要自己來(lái)保證 在會(huì)話處于不活躍狀態(tài)的時(shí)候,不要去修改它。

  活躍會(huì)話

  開(kāi)發(fā)者需要自己來(lái)追蹤每個(gè)用戶的活躍會(huì)話, 要知道每個(gè)用戶創(chuàng)建了多少活躍會(huì)話,每個(gè)活躍會(huì)話來(lái)自那個(gè) IP 地址, 活躍了多長(zhǎng)時(shí)間等。 PHP 不會(huì)自動(dòng)完成這項(xiàng)工作,需要開(kāi)發(fā)者來(lái)完成。

  有很多種方式可以做到追蹤用戶的活躍會(huì)話。 你可以通過(guò)在數(shù)據(jù)庫(kù)中存儲(chǔ)會(huì)話信息來(lái)跟蹤用戶會(huì)話。 由于會(huì)話是可以被垃圾收集器收集掉的, 所以你也需要處理被收集掉的會(huì)話數(shù)據(jù), 以保證數(shù)據(jù)庫(kù)中的數(shù)據(jù)和真實(shí)的活躍會(huì)話數(shù)據(jù)的一致性。

  一種很簡(jiǎn)單的方式就是使用“使用用戶 ID 作為會(huì)話 ID 前綴”,并且保存必要的信息到 $_SESSION 中。 大部分的數(shù)據(jù)庫(kù)產(chǎn)品對(duì)于字符串前綴查詢(譯注:也即右模糊查詢,可以利用索引)都有很好的性能表現(xiàn)。 為了實(shí)現(xiàn)這種方式,可以使用session_regenerate_id()和session_create_id()函數(shù)。

  警告

  永遠(yuǎn)不要使用機(jī)密數(shù)據(jù)作為會(huì)話 ID 前綴! 如果用戶 ID 屬于機(jī)密數(shù)據(jù),那么可以考慮使用hash_hmac()函數(shù)對(duì)其進(jìn)行摘要后再使用。

  警告

  必須啟用session.use_strict_mode配置項(xiàng)。 請(qǐng)確保已經(jīng)啟用, 否則活躍會(huì)話數(shù)據(jù)庫(kù)可能會(huì)被入侵。

  要能夠檢測(cè)對(duì)于過(guò)期會(huì)話數(shù)據(jù)的訪問(wèn), 基于時(shí)間戳的會(huì)話數(shù)據(jù)管理機(jī)制是必不可少的。 當(dāng)檢測(cè)到對(duì)于過(guò)期會(huì)話數(shù)據(jù)的訪問(wèn)時(shí),你應(yīng)該從相關(guān)用戶的活躍會(huì)話中刪除認(rèn)證信息, 避免攻擊者持續(xù)使用盜取的會(huì)話。

  會(huì)話和自動(dòng)登錄

  開(kāi)發(fā)者不應(yīng)該通過(guò)使用長(zhǎng)生命周期的會(huì)話ID來(lái)實(shí)現(xiàn)自動(dòng)登錄功能, 因?yàn)檫@種方式提高了會(huì)話被竊取的風(fēng)險(xiǎn)。 開(kāi)發(fā)者應(yīng)該自己實(shí)現(xiàn)自動(dòng)登錄的機(jī)制。

  在使用setcookie()的時(shí)候,傳入安全的一次性摘要結(jié)果作為自動(dòng)登錄信息。 建議使用比 SHA-2 更高強(qiáng)度的摘要算法(例如 SHA-256) 對(duì)random_bytes()隨機(jī)生成的數(shù)據(jù) (也可以讀取/dev/urandom設(shè)備)進(jìn)行摘要作為自動(dòng)登錄的信息。

  在用戶訪問(wèn)的時(shí)候,如果發(fā)現(xiàn)用戶尚未認(rèn)證, 那么就去檢查請(qǐng)求中是否包含了有效的一次性登錄信息。 如果包含有效的一次性登錄信息,那么就去認(rèn)證用戶,并且重新生成新的一次性登錄信息。 自動(dòng)登錄的關(guān)鍵信息一定是只能使用一次,永遠(yuǎn)不要重復(fù)使用一次性登錄信息。

  自動(dòng)登錄信息是長(zhǎng)生命周期的認(rèn)證信息, 所以必須要盡可能的妥善保護(hù)。 可以對(duì)于自動(dòng)登錄信息對(duì)應(yīng)的 cookie 設(shè)置路徑、僅允許 HTTP 訪問(wèn)、僅允許安全訪問(wèn) 等屬性來(lái)加以保護(hù),并且僅在必需的時(shí)候才傳送這個(gè) cookie。

  開(kāi)發(fā)者也要提供禁用自動(dòng)登錄的機(jī)制, 以及刪除不再需要的自動(dòng)登錄數(shù)據(jù)的能力。

  CSRF(跨站請(qǐng)求偽造)

  會(huì)話和認(rèn)證無(wú)法避免跨站請(qǐng)求偽造攻擊。 開(kāi)發(fā)者需要自己來(lái)實(shí)現(xiàn)保護(hù)應(yīng)用不受 CSRF 攻擊的功能。

  output_add_rewrite_var()函數(shù)可以用來(lái) 保護(hù)應(yīng)用免受 CSRF 攻擊。更多信息請(qǐng)參考文檔。

  注意:PHP 7.2.0 之前的版本,這個(gè)函數(shù)和會(huì)話 ID 使用了同樣的輸出緩沖以及 INI 設(shè)置項(xiàng), 所以不建議在 PHP 7.2.0 之前使用output_add_rewrite_var()函數(shù)。

  大部分 Web 應(yīng)用框架都提供了 CSRF 保護(hù)的特性。 詳細(xì)信息請(qǐng)參考你所用的 Web 框架的文檔。

  從 PHP 7.3 開(kāi)始,對(duì)于會(huì)話 cookie 增加了 SameSite 屬性, 這個(gè)屬性可以有效的降低 CSRF 攻擊的風(fēng)險(xiǎn)。

【PHP中使用會(huì)話控制】相關(guān)文章:

PHP中的trait是什么04-12

PHP中的Division by zero報(bào)錯(cuò)處理技巧02-23

PHP中數(shù)據(jù)類(lèi)型轉(zhuǎn)換的3種方式03-23

Word中各種通配符的使用09-18

在Dreamweaver中如何使用模板10-26

Excel中COLUMN函數(shù)的使用03-16

PHP基本語(yǔ)法04-29

php環(huán)境搭建06-11

PHP常量介紹04-21

PHP的基本作用03-17