在文章Cookie与登录注册中,我们已经实现了简单的注册和登录功能,并且登录后服务器会给客户端发送一个Cookie,登录后跳转首页可以显示自己的密码。
但是有一个问题:现在的Cookie是明文的,用户可以随意篡改Cookie,继而看到别人的密码。
1 | if (found) { |
上面代码中,如果认证用户登录成功,在Set-Cookie时会直接把email暴露给用户。
Session可以解决这个问题。
首先在服务器中声明一个空对象sessions(sessions是服务器的一块内存):(后端)
1 | var sessions = {} |
当用户登录成功后,把一个随机数sessionId通过Cookie传到客户端,并把这个sessionId和其对应的用户email存入session中。这样,用户不能直接从Cookie中看到email,但服务器仍然可以根据Cookie中的sessionId得到相匹配用户信息。(后端)
1 | if(found){ |
当用户跳转到首页时,根据Cookie从sessions中找到匹配的email:(后端)
1 | let cookies = '' //cookie初始为空字符串,避免没有cookie时下面代码中cookies.length报错 |
注意,现在用的是我们自己写的node.js服务器,如果关闭服务器(每次改完服务器代码都要重启服务器),所有内存会释放,sessions就清空了(sessions是服务器中的一块内存)。一般服务器是不关闭的,如果要关闭,也会先把sessions存在硬盘中。
Session与Cookie的关系:
一般来说,Session基于Cookie来实现。
Cookie:
- 服务器通过响应头Set-Cookie给客户端一串字符串
- 客户端每次访问相同域名的网页时,请求头必须带上这段字符串
- 客户端要在一段时间内保存这个Cookie
- Cookie默认在用户关闭页面后就失效,后台代码可以任意设置Cookie的过期时间
- 大小大概在4kb以内
Session:
- 将SessionID(随机数)通过Cookie发给客户端
- 客户端访问服务器时,服务器读取SessionID
- 服务器有一块内存(哈希表)保存了所有的session
- 通过SessionID服务器可以得到对应用户的隐私信息,如id,Email
- 这块内存(哈希表)就是服务器上的所有session
Session可以用LocalStorage+查询参数实现
一般来说,Session是基于Cookie实现的,因为Session将SessionID放在Cookie里发送给客户端。
但是,也可以不使用Cookie,用LocalStorage+查询参数来实现Session。
当认证用户登录成功后,不再Set-Cookies,而是直接把SessionID通过JSON传给前端:(后端)
1 | if(found){ |
前端拿到SessionID后把它存到LocalStorage里备用(因为客户端要在一段时间内持有这个SessionID),然后把SessionID作为查询参数插入到要跳转的页面:(前端 sign_in.html)
1 | $post('/sign_in', hash) |
再向首页发起请求时,服务器从查询参数中拿到SessionID,并在sessions中找到匹配的用户信息:(后端)
1 | let mySession = sessions[query.sessionId] |
完