這篇文章是前一篇文章(Cookie理論知識)的實踐性理解javascript
完整代碼:html
完整代碼前端
註冊時把帳號密碼寫入數據庫java
第一次登陸時服務器給瀏覽器發送Cookie.node
後臺的登陸路由代碼(nodejs):git
else if (path === '/sign_in' && method === 'POST') { readBody(request).then((body) => { let strings = body.split('&') // ['email=1', 'password=2', 'password_confirmation=3'] let hash = {} strings.forEach((string) => { // string == 'email=1' let parts = string.split('=') // ['email', '1'] let key = parts[0] let value = parts[1] hash[key] = decodeURIComponent(value) // hash['email'] = '1' }) let { email, password } = hash var users = fs.readFileSync('./db/users', 'utf8') try { users = JSON.parse(users) // [] } 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) {//關鍵在這裏,驗證成功,設置登陸Cookie爲登陸的郵箱,並放在響應裏發給瀏覽器 response.setHeader('Set-Cookie', `sign_in_email=${email}`) response.statusCode = 200 } else { response.statusCode = 401 } response.end() }) }
在登陸成功的一瞬間,須要後臺設置一個Cookie,記錄一下登錄的用戶id(這裏用郵箱表示,代碼在上面),而後發響應給瀏覽器
例如在服務器端設置響應頭:set-cookies:user_email=1@mtt.com
github
這時候咱們查看響應:數據庫
發現響應頭已經設置cookie.segmentfault
而後跳轉到主頁,這時候咱們查看跳轉到主頁的請求:後端
發現跳轉到主頁的請求頭中包含cookie字段(之後訪問這個域名都會帶着這個Cookie)!因此,就像上篇文章說的:
若是服務器給了瀏覽器一個setcookie的響應頭,那麼這個瀏覽器之後全部的請求,只要是相同的源(即就是上次給我發送Cookie的那個域名,域名和端口相同),那就麼就會把當時服務器發給這個瀏覽器的Cookie帶着
之後,瀏覽器一旦訪問這個路徑,瀏覽器就會附上這段 Cookie 發送給服務器
即:第一次請求,服務器爲瀏覽器設置Cookie.下次請求,瀏覽器帶上Cookie,發送給服務器.
第一次登陸的時候,服務器給瀏覽器的響應設置一個Cookie,set-cookies:user_email=1@mtt.com
,而後當瀏覽器下次進行請求的時候,發現Cookie中有名爲User_email的Cookie,並且我發送請求的域名仍是上次發給我帶Cookie的響應的那個域名.
那麼就無需再次登陸了.至關於服務器給瀏覽器發了進入門票,下次或下下次瀏覽器在進入服務器的時候給服務器看票就能夠了
首頁代碼:
<body> <h1>我是首頁</h1> <div class=""> <a href="./sign_up">註冊</a> <a href="./sign_in">登陸</a> </div> <h1>你的狀態是:__status__</h1> <h1>你的郵箱帳號是:__email__</h1> <h1>你的密碼是:__password__</h1> <a href="javascript:;" id="logOffBtn">退出登陸(刪除cookie)</a> </body> <script> logOffBtn.addEventListener("click", () => { // 刪除一個現存 Cookie 的惟一方法,是設置它的expires屬性爲一個過去的日期。 document.cookie = 'sign_in_email=;expires=Thu, 01-Jan-1970 00:00:01 GMT' window.location = "/" }) </script>
後臺路由代碼
if (path === '/') { response.statusCode = 200 let string = fs.readFileSync('./index.html') string = string.toString(); var users = fs.readFileSync('./db/users', 'utf8') users = JSON.parse(users)//轉化爲user對象數組 console.log(users); let cookies = request.headers.cookie || ''//['email=111', 'asdasd=111'] cookies = cookies.split("; ") let hash={} cookies.forEach((string)=>{ let parts = string.split("=") let key = parts[0] let value = parts[1] hash[key] = value; }) let eamil = hash.sign_in_email let foundedUser users.forEach((userObj)=>{ if(userObj.email===eamil){ foundedUser = userObj; } }) console.log(foundedUser); if(foundedUser){ string = string.replace('__status__', '已登陸') string = string.replace('__email__', foundedUser.email) string = string.replace('__password__', foundedUser.password) }else{ string = string.replace('__status__', '未登陸,請去登陸') string = string.replace('__email__', '沒') string = string.replace('__password__', '沒') } response.setHeader('Content-Type', 'text/html;charset=utf-8') response.write(string) response.end() }
在沒有Cookie的時候,首頁的狀態
登陸以後,後臺根據Cookie查詢數據庫,將用戶名與密碼傳到前臺的首頁上
退出登陸將刪除Cookie並刷新頁面,從新回到未登陸的狀態
咱們獲得Cookie的特色:
1.我在 Chrome 登陸了獲得 Cookie,用 Safari 訪問,Safari 會帶上 Cookie 嗎
no
2.Cookie 存在哪
Windows 存在 C 盤的一個文件裏
3.Cookie會被用戶篡改嗎?
能夠,例如在谷歌瀏覽器開發者模式下的application->Cookie中能夠手動修改,修改以後,下次發送請求時,附帶的就是修改後的Cookie
JS中也有能夠操做cookie的api
( 假如換成別的用戶的帳號,那麼還能夠登陸成功的話,就會存在風險問題.Session 來解決這個問題,防止用戶篡改)
後端能夠強制設置不容許修改Cookie,只要將Cookie的屬性設置爲Httponly
便可(還能夠手動改,可是JS改不了,也沒法獲取),具體語法看 MDN
4.Cookie 有效期嗎?
默認有效期20分鐘左右,不一樣瀏覽器策略不一樣(若是瀏覽器一直開着,那麼Cookie不會被刪除.若是關閉瀏覽器,那麼瀏覽器爲了安全考慮,20分鐘左右後可能會刪除Cookie.這也取決於服務器如何設置Cookie的有效期)
後端能夠強制設置有效期,具體語法看 MDN
Cookie 遵照同源策略嗎?
也有,不過跟 AJAX 的同源策略稍微有些不一樣。
當請求 qq.com 下的資源時,瀏覽器會默認帶上 qq.com 對應的 Cookie,不會帶上 baidu.com 對應的 Cookie
當請求 v.qq.com 下的資源時,瀏覽器不只會帶上 v.qq.com 的Cookie,還會帶上 qq.com 的 Cookie
另外 Cookie 還能夠根據路徑作限制,請自行了解,這個功能用得比較少。
先後端都要驗證郵箱格式是否正確,帳號密碼格式是否正確,兩次提交的密碼是否相同等。
由於黑客能夠繞過前端的js驗證流程,例如黑客能夠直接使用curl 進行請求的發送,直接與後臺服務器進行交互。
如圖:
因此後臺也須要進行表單驗證。
cookie:曲奇餅cache-control:緩存控制