昨天研究了網站的註冊流程,感興趣的能夠看下:從先後端分別學習——註冊/登陸流程1html
今天接着研究註冊/登陸流程之登陸。前端
首先來看一下登錄過程:
ajax
登陸邏輯和註冊邏輯基本一致,但登陸的過程只對數據庫進行讀,比對用戶的信息是否存在。數據庫
登陸頁面的 HTML 和 CSS 基本一致,這裏就不放上來了。segmentfault
當用戶註冊成功後,會跳轉到登陸頁面,進入登陸頁面,發送GET
請求,因此須要作一個路由,代碼和以前同樣,不熟悉的能夠看上面該出的連接,這裏就不放上來了。後端
當我檢測到服務器成功返回的狀態碼時,操做頁面跳轉至登陸頁面數組
window.location.herf = '/sign_in'
當用戶輸入用戶名和密碼後,點擊登陸按鈕,會發送POST
請求,服務器收到請求後,解析前端傳過來的數據,並讀取數據庫將兩者的信息進行比對,若是一致就說明是本人。和以前相同的地方,這邊就省略了。瀏覽器
let usersString = fs.readFileSync('./db/db','utf8') let usersArr = JSON.parse(usersString) let foundUser = false for(let i = 0; i < usersArr.length; i++){ if(usersArr[i].email === email && usersArr[i].password === password){ foundUser = true break } } if(foundUser){ response.statusCode = 200 response.write(`{ "successes":{ "success":"success" } }`) }else{ response.statusCode = 400 response.write(`{ "errors":{ "email":"foundUser" } }`) }
若是對比成功,說明該用戶已註冊過;若是對比失敗,返回對應的響應數據,讓前端提示用戶。安全
至此登陸流程作完,是否是以爲很簡單,在弄懂註冊流程後,登陸流程基本和它基本一致。服務器
Cookie
登陸流程雖然簡單,這不是咱們今天要研究的重點。
既然網站服務商須要用戶祖冊,那確定註冊用戶和非註冊用戶能訪問的頁面確定不同,那網站服務商怎麼區分註冊用戶和非註冊用戶呢?
對,就是Cookie
,當用戶登陸成功後,瀏覽器會向用戶發送一個 Cookie,用戶下次請求時會帶上Cookie
,後端都能匹配上Cookie
,就說明他是咱們的註冊用戶,能夠訪問這個頁面;若是Cookie
匹配不上,固然就禁止訪問了,Cookie
具體的參數下一篇討論,這裏先上手直接使用一下,看看效果。
當用戶登陸成功後,讓他跳轉至首頁,首頁上顯示用戶的密碼,固然實際工做中不能這樣用,這裏顯示密碼以示區分註冊用和非註冊用戶。
<h1>密碼:__password__</h1>
首頁很是簡單,__password__
處只是佔位符,若是是註冊用戶這裏會顯示對應的密碼。
在登陸成功後,服務器要給用戶發放一個Cookie
,這裏現已用戶的郵箱做爲Cookie
。
response.setHeader('Set-Cookie',`sign_in_email=${email}`)
設置了Cookie
以後,可看到響應頭中有了Set-Cookie
當跳轉首頁時,會帶上這個Cookie
。
後端繼續作一個路由,當登陸首頁時,判斷用戶是不是註冊用戶,只須要看它的Cookie
Cookie
讀取Cookie
時要注意兩點:
Cookie
是以"; "間隔,分號後面有空格Cookie
會報錯,初始化時要賦值一個空數組。if(path === '/home'){ let string = fs.readFileSync('./home.html','utf8') response.setHeader('Content-Type','text/html;charset=utf-8') let cookieArr = [] //初始化爲空數組 if(request.headers.cookie){ cookieArr = request.headers.cookie.split('; ') } let cookieHashes = {} //拆分紅須要的格式 cookieArr.forEach((e)=>{ let part =e.split('=') cookieHashes[part[0]] = part[1] }) response.write(string) response.end() }
Cookie
服務器發放的Cookie
是用戶的郵箱,因此這邊就比對數據庫裏的郵箱,若是匹配上,說明是註冊用戶
let {sign_in_email} = cookieHashes let usersString = fs.readFileSync('./db/db','utf8') let usersArr = JSON.parse(usersString) let foundUser for(let i = 0; i < usersArr.length; i++){ if(usersArr[i].email === sign_in_email){ // 驗證 Cookie foundUser = usersArr[i] break } }
驗證成功,給予訪問;驗證失敗,不給訪問。
if(foundUser){ response.statusCode = 200 string = string.replace('__password__',foundUser.password) }else{ response.statusCode = 400 string = string.replace('__password__','未註冊') }
驗證成功
驗證失敗
Session
用Cookie
有個很大的問題:用戶能夠隨意更改,若是有人知道了Cookie
的規律,那他就能夠隨意獲取用戶信息了。
爲解決這個問題,引入Session
,它是由一組隨機數組合的哈希表,當用戶登陸成功,原本發放Cookie
給用戶,如今變成發放Session
給用戶。
具體看下怎麼實現呢
var sessions = {} sessions[sessionId] = {sign_in_email:email} response.setHeader('Set-Cookie',`sessionId=${sessionId}`)
以前發放的Cookie
,如今變成了Session
服務器不能在讀Cookie
了,也要變成讀取Session
,才能正常顯示
let sessionsArr = [] if(request.headers.cookie){ sessionsArr = request.headers.cookie.split('; ') } let sessionHashes = {} sessionsArr.forEach((e)=>{ let part =e.split('=') sessionHashes[part[0]] = part[1] }) //經過讀取用戶的 sessionId 比對 session 表中的 email let sign_in_email if(sessionHashes.sessionId){ sign_in_email = sessions[sessionHashes.sessionId].sign_in_email }
上面代碼都同樣,這裏換了個變量而已,只有最後一句不同,若是sessionId
存在才能找到session
表中的用戶郵箱。
通過兩天研究註冊和登陸流程,弄清楚了各個環節,詳細的過程如上圖所示,有2
點須要瞭解:
Cookie
不可靠,用戶可隨意更改Session
通常用隨機數表示,加強了安全性,缺點太佔內存經過此次學習不只對ajax
、Promise
等技術瞭解更深,也大體明白了後端的工做流程。