摘要:昨天研究了網站的注冊流程,感興趣的可以看下從前后端分別學習注冊登錄流程今天接著研究注冊登錄流程之登錄。為解決這個問題,引入,它是由一組隨機數組合的哈希表,當用戶登錄成功,本來發放給用戶,現在變成發放給用戶。
昨天研究了網站的注冊流程,感興趣的可以看下:從前后端分別學習——注冊/登錄流程1
今天接著研究注冊/登錄流程之登錄。
登錄首先來看一下登陸過程:
登錄邏輯和注冊邏輯基本一致,但登錄的過程只對數據庫進行讀,比對用戶的信息是否存在。
登錄頁面的 HTML 和 CSS 基本一致,這里就不放上來了。
注冊成功后跳轉當用戶注冊成功后,會跳轉到登錄頁面,進入登錄頁面,發送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具體的參數下一篇討論,這里先上手直接使用一下,看看效果。
登錄成功后跳轉頁面當用戶登錄成功后,讓他跳轉至首頁,首頁上顯示用戶的密碼,當然實際工作中不能這樣用,這里顯示密碼以示區分注冊用和非注冊用戶。
密碼:__password__
首頁非常簡單,__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__","未注冊") }
驗證成功
驗證失敗
用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等技術了解更深,也大致明白了后端的工作流程。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108396.html
摘要:上面的寫法有個問題點擊按鈕發送請求后,客戶端一直收不到響應,就會報錯其實傳送的時是一個異步的過程,里面還沒執行完,外面就已經執行了,這邊可以用來解決下這個問題內部返回一個對象,成功調用函數,失敗調用函數,這邊就默認它會成功。 今天來研究一個小小的功能。當我們進入一個網站,它怎么判斷我是不是它的用戶?讓用戶登錄唄,如果它能正常登錄,它就是我的用戶唄?你有沒想過它是怎么判斷我是不是它用戶的...
摘要:用存儲用戶路由守衛路由中設置的字段就在當中每次跳轉的路徑登錄狀態下訪問頁面會跳到如果沒有訪問任何頁面。一個簡單的保存登錄狀態的小。 Vue項目中實現用戶登錄及token驗證 先說一下我的實現步驟: 使用easy-mock新建登錄接口,模擬用戶數據 使用axios請求登錄接口,匹配賬號和密碼 賬號密碼驗證后, 拿到token,將token存儲到sessionStorage中,并跳轉到首...
摘要:其實,該復雜的東西在哪放都復雜,只不過現在更清晰一點使用不好的地方就是太繁瑣了,定義各種各種組件。。。。。 之前做了個好電影搜集的小應用,前端采用react,后端采用express+mongodb,最近又將組件間的狀態管理改成了redux,并加入了redux-saga來管理異步操作,記錄一些總結 在線地址 手機模式 源碼 主要功能 爬取豆瓣電影信息并錄入MongoDB 電影列表展示...
摘要:本使用創建本地服務器,在就能完成全部流程,并不需要線上服務器。路徑要與后端接口一致。后端返回成功后,前端數據中對應的元素也要刪掉,更新視圖。控制器里拿一個方法出來說一下吧,完整的代碼都在。讀取操作完成后調用釋放連接。 寫在前面 本文只是本人學習過程的一個記錄,并不是什么非常嚴謹的教程,希望和大家一起共同進步。也希望大家能指出我的問題。適合有一定基礎,志在全棧的前端初學者學習,從點擊按鈕...
閱讀 3766·2021-09-22 15:17
閱讀 1953·2021-09-22 14:59
閱讀 2351·2020-12-03 17:00
閱讀 3212·2019-08-30 15:55
閱讀 489·2019-08-30 11:23
閱讀 3492·2019-08-29 13:56
閱讀 522·2019-08-29 12:54
閱讀 2261·2019-08-29 12:49