一塊小餅乾(Cookie)的故事-下篇

上篇介紹了註冊的基本流程,下篇簡單的講講登陸的流程以及Cookie的出現javascript

實現登陸的小功能

當你在瀏覽器的輸入框裏輸入localhost:8080/sign_in的時候,會發起GET請求,去訪問sign_in.htmlphp

if (path === '/sign_up' && method === 'GET') {
  let string = fs.readFileSync('./sign_up.html', 'utf8')
  response.statusCode = 200
  response.setHeader('Content-Type', 'text/html;charset=utf-8')
  response.write(string)
  response.end()
}
複製代碼

CSS佈局與上篇的佈局基本同樣,略去不表~html

比對用戶的信息與數據庫裏面的信息是否匹配

依然是上篇的套路,得到用戶formdata後,分析數據,和數據庫裏面的比對java

var users = fs.readFileSync('./db/users', 'utf8')
try {
	users = JSON.parse(users) //[] JSON也支持數組
} catch (exception) {
	users = []
}

let found 
for (let i = 0; i < users.length; i++) {
if (users[i].email === email && users[i].password === password) {
  found = true
  break
  }
}
if (found) {
  response.setHeader('Set-Cookie', `sign_in_email=${email};HTTPOnly`)
  response.statusCode = 200
} else {
  response.statusCode = 401
}
複製代碼

不一樣的是引入了一個header,也就是今天的主角--Cookienode

其實這和日常上網的情形相似的,有時候咱們訪問一些購物網站,並無登陸,可是你在購物車裏面添加東西了,當你逛了之後再回來的時候,發現購物車裏面有你的記錄,幫你作這個事的也是cookie。git

由於HTTP協議是無狀態的,即服務器不知道用戶上一次作了什麼,這嚴重阻礙了交互式Web應用程序的實現。在典型的網上購物場景中,用戶瀏覽了幾個頁面,買了一盒餅乾和兩瓶飲料。最後結賬時,因爲HTTP的無狀態性,不經過額外的手段,服務器並不知道用戶到底買了什麼,因此Cookie就是用來繞開HTTP的無狀態性的「額外手段」之一。服務器能夠設置或讀取Cookies中包含信息,藉此維護用戶跟服務器會話中的狀態。github

設置頭

能夠看出,當你在sign_in發起GET請求並設置了Set-Cookie以後,其餘的同源的頁面,又都會帶上Cookie,也就能保證同源的網頁向服務器發起請求的時候,服務器可以明白,你己經是登陸的用戶了,與那些沒有拿到cookie的頁面區別開來。數據庫

Cookie的入門

爲何要在cookie裏面寫上HttpOnly呢,由於這個能夠防止有些牛人使用JS修改Cookie的內容。後端

  • 若是不寫這個的話,可使用js修改的

js修改cookie

寫了HttpOnly以後將沒法修改數組

沒法修改

_ga是啥

這個是Chrome的功能,用於分析cookie的

每一部分的做用詳見這裏

Cookie的特色

經過上述的例子,能夠總結幾點重要的特色

  1. 服務器經過 Set-Cookie 響應頭設置 Cookie
  2. 瀏覽器獲得 Cookie 以後,每次請求都要帶上 Cookie
  3. 服務器讀取 Cookie 就知道登陸用戶的信息(email)

固然了,還有幾個問題須要解答一下。

  1. Cookie 存在哪 存在硬盤的一個文件裏面
  2. Cookie會被用戶篡改嗎? 能夠,也就是說它並不安全的。

不安全

  1. Cookie 有效期嗎?

默認有效期20分鐘左右,不一樣瀏覽器策略不一樣 後端能夠強制設置有效期

Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
複製代碼

具體語法看 Set-Cookie

用戶登陸後,首頁顯示不一樣

既然你成功登陸,理應跳轉到首頁,並顯示相應的界面。

$.post('/sign_in', hash)
.then((response) => {
  window.location.href = '/'
}, 
(request) => {
  alert('郵箱與密碼不匹配')
  }
)
複製代碼

而後首頁的信息應該根據用戶信息作出相應的變化

let cookies = request.headers.cookie.split('; ') //['email=..@..', 'a=1']
let hash = {}
cookies.forEach((cookie) => {
  let parts = cookie.split('=')
  let key = parts[0]
  let value = parts[1]
  hash[key] = value
})
let email = hash.sign_in_email
let users = fs.readFileSync('./db/users', 'utf8')
users = JSON.parse(users)
let foundUser
for (let i = 0; i < users.length; i++) {
  if (users[i].email === email) {
    foundUser = users[i]
    break
  }
}
if (foundUser) {
  string = string.replace('email', foundUser.email)
} else {
  string = string.replace('恭喜,email你已成功登陸', '沒有該用戶')
}
複製代碼

這裏的代碼邏輯與上篇的基本一致,惟一的不一樣在於第一行代碼

let cookies = request.headers.cookie.split('; ') //['email=..@..', 'a=1']

爲何用字符來分割呢,這是由於能夠有多個cookie

多個cookie

Cookie的兩個做用

通常來講常見的做用有以下兩個:

  1. 識別用戶的身份。當用戶A去訪問localhost:8080的時候,服務器會給A一個獨一無二的id=00A(這就是cookie),當用戶A訪問localhost:8080的其餘網頁的時候,都會帶着那個獨一無二的id。當B用戶來訪問localhost:8080的時候,服務器發現他沒有任何標識,也會給他一個獨一無二的id=00B,因此藉助cookie服務器端就可以分清楚誰是誰了。
  2. 記錄你的瀏覽歷史。最多見的需求就是你去逛購物網站,你添加到購物車裏面的東西過幾天必定會在,而不會憑空消失了。例如A用戶去taobao.com去買點東西,添加了一個熱水壺、一部小米手機到購物車裏面,那麼服務器端能夠改寫你上面的cookie使之具體化「id=00A; cart=A1,A2」,表示你購物車裏面買了倆東西。你過幾天想起來了,去購物車裏面看,熱水壺、小米手機還在裏面。瀏覽器並不會刪除你存到硬盤上的cookie。

一張圖總結註冊登陸的過程

登陸註冊的過程

接下來能夠去搞一搞其餘的,像什麼session LocalStorage……(@ο@) 哇~

代碼連接sign_in.html

server.js

相關文章
相關標籤/搜索