Session

在文章Cookie與登錄注冊中,我們已經(jīng)實(shí)現(xiàn)了簡單的注冊和登錄功能,并且登錄后服務(wù)器會給客戶端發(fā)送一個Cookie,登錄后跳轉(zhuǎn)首頁可以顯示自己的密碼。

但是有一個問題:現(xiàn)在的Cookie是明文的,用戶可以隨意篡改Cookie,繼而看到別人的密碼。

if (found) {
    response.setHeader('Set-Cookie', `sign_in_email=${email}`)
    response.statusCode = 200
}

上面代碼中,如果認(rèn)證用戶登錄成功,在Set-Cookie時會直接把email暴露給用戶。

Session可以解決這個問題。
首先在服務(wù)器中聲明一個空對象sessions(sessions是服務(wù)器的一塊內(nèi)存):(后端)

var sessions  = {}

當(dāng)用戶登錄成功后,把一個隨機(jī)數(shù)sessionId通過Cookie傳到客戶端,并把這個sessionId和其對應(yīng)的用戶email存入session中。這樣,用戶不能直接從Cookie中看到email,但服務(wù)器仍然可以根據(jù)Cookie中的sessionId得到相匹配用戶信息。(后端)

if(found){
  let sessionId = Math.random() * 1000000
  session[sessionId] = {sign_in_email: email}
  response.setHeader('Set-Cookie', `sessionId = ${sessionId}`)
  response.statusCode = 200 
}

當(dāng)用戶跳轉(zhuǎn)到首頁時,根據(jù)Cookie從sessions中找到匹配的email:(后端)

let cookies = '' //cookie初始為空字符串,避免沒有cookie時下面代碼中cookies.length報錯
if(request.headers.cookie){ //判斷是否有cookie,避免沒有cookie時split方法報錯
    cookies = request.headers.cookie.split('; ')  // ['email=1@', 'a=1', 'b=2']
}

let hash = {}
for (let i = 0; i < cookies.length; i++) {
    let parts = cookies[i].split('=')
    let key = parts[0]
    let value = parts[1]
    hash[key] = value
}
let email = sessions[hash.sessionId].sign_in_email

注意,現(xiàn)在用的是我們自己寫的node.js服務(wù)器,如果關(guān)閉服務(wù)器(每次改完服務(wù)器代碼都要重啟服務(wù)器),所有內(nèi)存會釋放,sessions就清空了(sessions是服務(wù)器中的一塊內(nèi)存)。一般服務(wù)器是不關(guān)閉的,如果要關(guān)閉,也會先把sessions存在硬盤中。

Session與Cookie的關(guān)系:
一般來說,Session基于Cookie來實(shí)現(xiàn)。

Cookie:

  1. 服務(wù)器通過響應(yīng)頭Set-Cookie給客戶端一串字符串
  2. 客戶端每次訪問相同域名的網(wǎng)頁時,請求頭必須帶上這段字符串
  3. 客戶端要在一段時間內(nèi)保存這個Cookie
  4. Cookie默認(rèn)在用戶關(guān)閉頁面后就失效,后臺代碼可以任意設(shè)置Cookie的過期時間
  5. 大小大概在4kb以內(nèi)

Session:

  1. 將SessionID(隨機(jī)數(shù))通過Cookie發(fā)給客戶端
  2. 客戶端訪問服務(wù)器時,服務(wù)器讀取SessionID
  3. 服務(wù)器有一塊內(nèi)存(哈希表)保存了所有的session
  4. 通過SessionID服務(wù)器可以得到對應(yīng)用戶的隱私信息,如id,Email
  5. 這塊內(nèi)存(哈希表)就是服務(wù)器上的所有session

Session可以用LocalStorage+查詢參數(shù)實(shí)現(xiàn)

一般來說,Session是基于Cookie實(shí)現(xiàn)的,因?yàn)镾ession將SessionID放在Cookie里發(fā)送給客戶端。
但是,也可以不使用Cookie,用LocalStorage+查詢參數(shù)來實(shí)現(xiàn)Session。

當(dāng)認(rèn)證用戶登錄成功后,不再Set-Cookies,而是直接把SessionID通過JSON傳給前端:(后端)

if(found){
  let sessionId = Math.random() * 1000000
  sessions[sessionId] = {sign_in_email: email}
  response.write(`{"sessionId": ${sessionId}}`)
  response.statusCode = 200
}

前端拿到SessionID后把它存到LocalStorage里備用(因?yàn)榭蛻舳艘谝欢螘r間內(nèi)持有這個SessionID),然后把SessionID作為查詢參數(shù)插入到要跳轉(zhuǎn)的頁面:(前端 sign_in.html)

$post('/sign_in', hash)
    .then{(response) => {
            let object = JSON.parse(response)
            localStorage.setItem('sessionId', object.sessionId)
            window.local.href = `/?sessionId=${object.sessionId}`
        }, (request) =>{
            alert('郵箱與密碼不匹配')
        }}

再向首頁發(fā)起請求時,服務(wù)器從查詢參數(shù)中拿到SessionID,并在sessions中找到匹配的用戶信息:(后端)

let mySession = sessions[query.sessionId]
let email
if(mySession){
    email = mySession.sign_in_email
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄Cookie機(jī)制什么是CookieCookie的不可跨域名性Unicode編碼:保存中文BASE64編碼:保存...
    Tomatoro閱讀 17,064評論 7 186
  • 轉(zhuǎn)自 :http://blog.csdn.net/taoff/articles/1921009.aspx 一、術(shù)語...
    stone_yao閱讀 6,392評論 0 31
  • 會話(Session)跟蹤是Web程序中常用的技術(shù),用來跟蹤用戶的整個會話。常用的會話跟蹤技術(shù)是Cookie與Se...
    chinariver閱讀 5,792評論 1 49
  • 背景在HTTP協(xié)議的定義中,采用了一種機(jī)制來記錄客戶端和服務(wù)器端交互的信息,這種機(jī)制被稱為cookie,cooki...
    時芥藍(lán)閱讀 2,478評論 1 17
  • 彼得和莎莫是一對伴侶。他們是我寫出來的。沒有爭議。 伴侶。有爭議的是這個定義。我這么寫,是因?yàn)楸说眠@么堅(jiān)持。情侶不...
    前折口閱讀 283評論 4 7

友情鏈接更多精彩內(nèi)容