本文轉(zhuǎn)載自知乎用戶小雷回答
首先,基于以上幾位朋友提到的瓶蚂,SESSION信息存儲(chǔ)在服務(wù)端骤公,相對(duì)于存儲(chǔ)在客戶端的COOKIE更為安全,所以正常一般網(wǎng)站在用于“判斷用戶是否登錄”時(shí)扬跋,確實(shí)是使用SESSION阶捆,例如可以在SESSION里存儲(chǔ)如下一個(gè)數(shù)組:
//驗(yàn)證用戶名和密碼成功后
$_SESSION['userinfo'] = [
'uid' => 123,
'username' => 'testuser'
];
而后在需要驗(yàn)證登錄的地方加入類似如下判斷
if(empty($_SESSION['userinfo']) || empty($_SESSION['userinfo']['uid'])){
//未登錄,引導(dǎo)登錄
}
以上是使用SESSION做用戶登錄的基本存儲(chǔ)和驗(yàn)證邏輯钦听,當(dāng)然實(shí)際開發(fā)過程中會(huì)將這部分的代碼封裝
我們都知道洒试,SESSION一般是通過在COOKIE里記錄一個(gè)KEY為PHPSESSID的COOKIE來保持上下文的,而這個(gè)PHPSESSID的COOKIE的有效期是設(shè)置為“會(huì)話”朴上,意味著關(guān)閉瀏覽器后該COOKIE被銷毀垒棋,相應(yīng)的后端SESSION也就銷毀,如圖
另外痪宰,由于PHP的Session本身就有GC的機(jī)制叼架,一般默認(rèn)1440秒內(nèi)頁面沒有刷新動(dòng)作(準(zhǔn)確的說是沒有新的請(qǐng)求來刷新該PHPSESSID的生命周期),該SESSION也就被自動(dòng)回收衣撬,伴隨著用戶的登錄就失效了乖订。
而題主關(guān)注的是如何實(shí)現(xiàn)這個(gè)“記住我”的功能,首先具练,雖然COOKIE保存在客戶端乍构,不安全,易被偽造扛点,這是客觀存在的事實(shí)哥遮,但要實(shí)現(xiàn)這個(gè)“記住我”岂丘,還確實(shí)就得用到COOKIE,我們能做的是盡量去提高偽造的門檻眠饮。
這邊僅提供一個(gè)參考的設(shè)計(jì)方案奥帘,
1、將用戶信息仪召,比如一個(gè)['uid'=>123, 'username'=>'testuser']的數(shù)組翩概,序列化后成為字符串,使用可逆加密算法加密該字符串返咱,寫到一個(gè)Key為userinfo的COOKIE里
2、由于可逆加密算法容易被解密牍鞠,一旦加密的規(guī)則被別人猜測(cè)到以后咖摹,就可以輕易篡改這個(gè)COOKIE的內(nèi)容,然后自行根據(jù)加密規(guī)則加密后偽造难述,所以萤晴,我們另外加入一個(gè)infodig的COOKIE,是將以上的userinfo的COOKIE內(nèi)容胁后,加入salt后使用不可逆加密算法生成散列店读,至于salt咱們可以自己定,總之要對(duì)外保密攀芯,不可逆算法例如md5屯断,甚至多次加鹽多次md5
3、以上兩個(gè)COOKIE侣诺,為增強(qiáng)安全性殖演,防止用戶被XSS攻擊后拿到,可以設(shè)置http-only屬性
服務(wù)端判斷存在以上兩個(gè)COOKIE后
1年鸳、驗(yàn)證infodig與userinfo是否匹配(將userinfo的內(nèi)容使用生成infodig的方法計(jì)算后趴久,與COOKIE傳上來的infodig匹配是否一致)
2、infodig驗(yàn)證通過后搔确,使用解密算法解密userinfo串彼棍,得到用戶信息,如果用戶信息里的uid存在用戶表中膳算,則寫SESSION座硕,通過SESSION保持本次會(huì)話
總而言之,使用COOKIE記錄用戶信息是可行的(當(dāng)然不建議把用戶敏感的東西存在COOKIE涕蜂,例如郵箱坎吻、手機(jī)、甚至密碼,只記錄對(duì)登錄有用的部分笼裳,例如uid、username等標(biāo)識(shí)佛舱,以及nickname可能會(huì)在某些地方提升用戶體驗(yàn))诸尽,可以確定的是原杂,這個(gè)COOKIE對(duì)用戶可見,我們要做的就是兩點(diǎn):
1您机、盡量讓用戶看不懂穿肄,而只有我們服務(wù)端自己認(rèn)識(shí)(可逆加密算法);
2际看、即使用戶看懂了咸产,他也不能夠輕易的偽造(不可逆的散列算法)