Session

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

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

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

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

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

var sessions  = {}

當用戶登錄成功后,把一個隨機數(shù)sessionId通過Cookie傳到客戶端,并把這個sessionId和其對應的用戶email存入session中。這樣,用戶不能直接從Cookie中看到email,但服務器仍然可以根據(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 
}

當用戶跳轉到首頁時,根據(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服務器,如果關閉服務器(每次改完服務器代碼都要重啟服務器),所有內(nèi)存會釋放,sessions就清空了(sessions是服務器中的一塊內(nèi)存)。一般服務器是不關閉的,如果要關閉,也會先把sessions存在硬盤中。

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

Cookie:

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

Session:

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

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

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

當認證用戶登錄成功后,不再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里備用(因為客戶端要在一段時間內(nèi)持有這個SessionID),然后把SessionID作為查詢參數(shù)插入到要跳轉的頁面:(前端 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ā)起請求時,服務器從查詢參數(shù)中拿到SessionID,并在sessions中找到匹配的用戶信息:(后端)

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

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

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

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

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