從先後端分別學習——註冊/登陸流程2

昨天研究了網站的註冊流程,感興趣的能夠看下:從先後端分別學習——註冊/登陸流程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時要注意兩點:

  1. Cookie是以"; "間隔,分號後面有空格
  2. 如非註冊用戶訪問,沒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點須要瞭解:

  1. Cookie不可靠,用戶可隨意更改
  2. Session通常用隨機數表示,加強了安全性,缺點太佔內存

經過此次學習不只對ajaxPromise等技術瞭解更深,也大體明白了後端的工做流程。

相關文章
相關標籤/搜索