摘要:昨天研究了網(wǎng)站的注冊流程,感興趣的可以看下從前后端分別學(xué)習(xí)注冊登錄流程今天接著研究注冊登錄流程之登錄。為解決這個問題,引入,它是由一組隨機(jī)數(shù)組合的哈希表,當(dāng)用戶登錄成功,本來發(fā)放給用戶,現(xiàn)在變成發(fā)放給用戶。
昨天研究了網(wǎng)站的注冊流程,感興趣的可以看下:從前后端分別學(xué)習(xí)——注冊/登錄流程1
今天接著研究注冊/登錄流程之登錄。
登錄首先來看一下登陸過程:
登錄邏輯和注冊邏輯基本一致,但登錄的過程只對數(shù)據(jù)庫進(jìn)行讀,比對用戶的信息是否存在。
登錄頁面的 HTML 和 CSS 基本一致,這里就不放上來了。
注冊成功后跳轉(zhuǎn)當(dāng)用戶注冊成功后,會跳轉(zhuǎn)到登錄頁面,進(jìn)入登錄頁面,發(fā)送GET請求,所以需要做一個路由,代碼和之前一樣,不熟悉的可以看上面該出的鏈接,這里就不放上來了。
當(dāng)我檢測到服務(wù)器成功返回的狀態(tài)碼時,操作頁面跳轉(zhuǎn)至登錄頁面
window.location.herf = "/sign_in"
當(dāng)用戶輸入用戶名和密碼后,點(diǎn)擊登錄按鈕,會發(fā)送POST請求,服務(wù)器收到請求后,解析前端傳過來的數(shù)據(jù),并讀取數(shù)據(jù)庫將二者的信息進(jìn)行比對,如果一致就說明是本人。和之前相同的地方,這邊就省略了。
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" } }`) }
如果對比成功,說明該用戶已注冊過;如果對比失敗,返回對應(yīng)的響應(yīng)數(shù)據(jù),讓前端提示用戶。
至此登錄流程做完,是不是覺得很簡單,在弄懂注冊流程后,登錄流程基本和它基本一致。
Cookie登錄流程雖然簡單,這不是我們今天要研究的重點(diǎn)。
既然網(wǎng)站服務(wù)商需要用戶祖冊,那肯定注冊用戶和非注冊用戶能訪問的頁面肯定不一樣,那網(wǎng)站服務(wù)商怎么區(qū)分注冊用戶和非注冊用戶呢?
對,就是Cookie,當(dāng)用戶登錄成功后,瀏覽器會向用戶發(fā)送一個 Cookie,用戶下次請求時會帶上Cookie,后端都能匹配上Cookie,就說明他是我們的注冊用戶,可以訪問這個頁面;如果Cookie匹配不上,當(dāng)然就禁止訪問了,Cookie具體的參數(shù)下一篇討論,這里先上手直接使用一下,看看效果。
登錄成功后跳轉(zhuǎn)頁面當(dāng)用戶登錄成功后,讓他跳轉(zhuǎn)至首頁,首頁上顯示用戶的密碼,當(dāng)然實(shí)際工作中不能這樣用,這里顯示密碼以示區(qū)分注冊用和非注冊用戶。
密碼:__password__
首頁非常簡單,__password__處只是占位符,如果是注冊用戶這里會顯示對應(yīng)的密碼。
在登錄成功后,服務(wù)器要給用戶發(fā)放一個Cookie,這里現(xiàn)已用戶的郵箱作為Cookie。
response.setHeader("Set-Cookie",`sign_in_email=${email}`)
設(shè)置了Cookie之后,可看到響應(yīng)頭中有了Set-Cookie
當(dāng)跳轉(zhuǎn)首頁時,會帶上這個Cookie。
后端繼續(xù)做一個路由,當(dāng)?shù)卿浭醉摃r,判斷用戶是否是注冊用戶,只需要看它的Cookie
讀取Cookie讀取Cookie時要注意兩點(diǎn):
多Cookie是以"; "間隔,分號后面有空格
如非注冊用戶訪問,沒Cookie會報(bào)錯,初始化時要賦值一個空數(shù)組。
if(path === "/home"){ let string = fs.readFileSync("./home.html","utf8") response.setHeader("Content-Type","text/html;charset=utf-8") let cookieArr = [] //初始化為空數(shù)組 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() }驗(yàn)證Cookie
服務(wù)器發(fā)放的Cookie是用戶的郵箱,所以這邊就比對數(shù)據(jù)庫里的郵箱,如果匹配上,說明是注冊用戶
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){ // 驗(yàn)證 Cookie foundUser = usersArr[i] break } }權(quán)限分配
驗(yàn)證成功,給予訪問;驗(yàn)證失敗,不給訪問。
if(foundUser){ response.statusCode = 200 string = string.replace("__password__",foundUser.password) }else{ response.statusCode = 400 string = string.replace("__password__","未注冊") }
驗(yàn)證成功
驗(yàn)證失敗
用Cookie有個很大的問題:用戶可以隨意更改,如果有人知道了Cookie的規(guī)律,那他就可以隨意獲取用戶信息了。
為解決這個問題,引入Session,它是由一組隨機(jī)數(shù)組合的哈希表,當(dāng)用戶登錄成功,本來發(fā)放Cookie給用戶,現(xiàn)在變成發(fā)放Session給用戶。
具體看下怎么實(shí)現(xiàn)呢
var sessions = {} sessions[sessionId] = {sign_in_email:email} response.setHeader("Set-Cookie",`sessionId=${sessionId}`)
之前發(fā)放的Cookie,現(xiàn)在變成了Session
服務(wù)器不能在讀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表中的用戶郵箱。
經(jīng)過兩天研究注冊和登錄流程,弄清楚了各個環(huán)節(jié),詳細(xì)的過程如上圖所示,有2點(diǎn)需要了解:
Cookie不可靠,用戶可隨意更改
Session一般用隨機(jī)數(shù)表示,增強(qiáng)了安全性,缺點(diǎn)太占內(nèi)存
通過這次學(xué)習(xí)不僅對ajax、Promise等技術(shù)了解更深,也大致明白了后端的工作流程。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/108396.html
摘要:上面的寫法有個問題點(diǎn)擊按鈕發(fā)送請求后,客戶端一直收不到響應(yīng),就會報(bào)錯其實(shí)傳送的時是一個異步的過程,里面還沒執(zhí)行完,外面就已經(jīng)執(zhí)行了,這邊可以用來解決下這個問題內(nèi)部返回一個對象,成功調(diào)用函數(shù),失敗調(diào)用函數(shù),這邊就默認(rèn)它會成功。 今天來研究一個小小的功能。當(dāng)我們進(jìn)入一個網(wǎng)站,它怎么判斷我是不是它的用戶?讓用戶登錄唄,如果它能正常登錄,它就是我的用戶唄?你有沒想過它是怎么判斷我是不是它用戶的...
摘要:用存儲用戶路由守衛(wèi)路由中設(shè)置的字段就在當(dāng)中每次跳轉(zhuǎn)的路徑登錄狀態(tài)下訪問頁面會跳到如果沒有訪問任何頁面。一個簡單的保存登錄狀態(tài)的小。 Vue項(xiàng)目中實(shí)現(xiàn)用戶登錄及token驗(yàn)證 先說一下我的實(shí)現(xiàn)步驟: 使用easy-mock新建登錄接口,模擬用戶數(shù)據(jù) 使用axios請求登錄接口,匹配賬號和密碼 賬號密碼驗(yàn)證后, 拿到token,將token存儲到sessionStorage中,并跳轉(zhuǎn)到首...
摘要:其實(shí),該復(fù)雜的東西在哪放都復(fù)雜,只不過現(xiàn)在更清晰一點(diǎn)使用不好的地方就是太繁瑣了,定義各種各種組件。。。。。 之前做了個好電影搜集的小應(yīng)用,前端采用react,后端采用express+mongodb,最近又將組件間的狀態(tài)管理改成了redux,并加入了redux-saga來管理異步操作,記錄一些總結(jié) 在線地址 手機(jī)模式 源碼 主要功能 爬取豆瓣電影信息并錄入MongoDB 電影列表展示...
摘要:本使用創(chuàng)建本地服務(wù)器,在就能完成全部流程,并不需要線上服務(wù)器。路徑要與后端接口一致。后端返回成功后,前端數(shù)據(jù)中對應(yīng)的元素也要刪掉,更新視圖??刂破骼锬靡粋€方法出來說一下吧,完整的代碼都在。讀取操作完成后調(diào)用釋放連接。 寫在前面 本文只是本人學(xué)習(xí)過程的一個記錄,并不是什么非常嚴(yán)謹(jǐn)?shù)慕坛?,希望和大家一起共同進(jìn)步。也希望大家能指出我的問題。適合有一定基礎(chǔ),志在全棧的前端初學(xué)者學(xué)習(xí),從點(diǎn)擊按鈕...
閱讀 3773·2021-09-22 15:17
閱讀 1959·2021-09-22 14:59
閱讀 2357·2020-12-03 17:00
閱讀 3221·2019-08-30 15:55
閱讀 494·2019-08-30 11:23
閱讀 3494·2019-08-29 13:56
閱讀 527·2019-08-29 12:54
閱讀 2265·2019-08-29 12:49