cookie和session的看法

要知道cookie和session都是前端面试非常重要的点,所以简单写一个文章来汇总一下想法。

为什么需要cookie?

  1. Http是无状态协议,他不对之前发生过的请求和响应的状态进行管理。也就是说,http无法根据根据之前的状态进行本次的请求处理。(eg,就像你和一个记忆不好的保安交流:你:我是住这个小区的。他:ok。然后你:开门让我进去。他:你是谁,只有住这个小区的才可以进去。就是他无法记住你以前说的话。)所以需要引入cookie进行状态管理。(eg:由于这个保安,很多人进不去,so居委会给每个住户发一个门牌,进门的时候只要给门房看这个徽章,他就让你进去。)
  2. Http响应通过
setHeader('Set-Cookie','cookieName=CookieValue;HttpOnly')

设置cookie.

Tips

一般都要加上HttpOnly!!!!!!!

这是为了防止前端操作cookie。因为一般来说,前端是不允许操作cookie的。因为如果前端能操作cookie,那么用户在浏览器的控制台也可以操作了。

cookie是浏览器下发给服务器的一段字符串

浏览器必须保存这个cookie(除非用户自己删除)

之后发起相同二级域名的请求(任何请求)时,浏览器必须附上cookie

结合注册与登录过程原理弄懂cookie

注册

这一步其实和cookie没什么关系,但是为了更好的理解,建议还是仔细看看

  1. 如果我第一次浏览一个网页,我必须注册账号
  2. 假如我的用户ID为:123 密码为:123456。然后我点击注册按钮,其实就是往服务器发送了一个post请求,会把我所填的信息上传给服务器。
  3. 服务区读取我上传的数据:
//生成新数组
const array=[]
//监听request的data事件,把数据push到array里面
request.on('data', (chunk) => {
            array.push(chunk)
})
//监听request的end事件,数据上传完全后,用buffer.concat().toString()把数据转换成字符串
 request.on('end', () => {
            const string = Buffer.concat(array).toString()
})

  1. 服务器收到我上传的数据后,会把信息储存在本地的user.json文件里。
  2. 一般来说,!!!!密码是不会明文储存的。
    因为如果名文存储密码,如果服务器的user.json文件被窃取了,那么所有的用户信息就被窃取了,这就是常说的“脱库’”
  3. 所以为了安全起见,会在后端生成一个随机数random,然后把密码和random结合起来,再用sha256进行单向散射,生成一个值,然后再把生成的随机数和散射值存储在user.json,如一下格式;
{{"user_id":1,"name":"123","random":1235,"secret":sha256(random+密码)},
 {"user_id":2,"name":"234","random":5465,"secret":sha256(random+密码)}
}

登录

  1. 我输入注册过的用户名和密码,点击登录。实际上也是发送了一个Http的post请求,把输入的用户名和密码发送给服务器。
  2. 简单过一下服务器怎么处理我上传的数据
    首先会根据我提交的用户名,在user.json里面查找是否有匹配的用户。如果找到了,会从文件里面提取出所对应的random,然后加上我的密码,用sha256进行单向散射,所得的散射值与文件所储存的散射值对比,如果一致,即通过验证。
  3. 直到现在,cookie还是没有出现,接下来该它发挥作用了!
    一般来说,输入争取的用户名后,会跳转到home页面,每个user的home页面应该是不一样的(比如说,如果我是liu,那么我的home页面会显示“hello,liu”;如果我是jack,那么我的home页面会显示“hello,jack”)。但是游览器怎么知道我是哪个user呢??
  4. 对应的解决方法就是服务器给我(浏览器)发送一张身份证,那么以后我发起任何请求都会带上这张身份证,后台服务器会根据我的身份证号码不同,给我返回不同的响应。这个身份证就是cookie。
    看看服务器user.json存储的我的数据:
{"user_id":1,"name":"123","random":1235,"secret":sha256(random+密码)},

那么服务器给我发送的cookie就是user_id=1
用node.js设置cookie:

response.setHeader("Set-Cookie","user_id=1;HttpOnly")


到这里,cookie的故事就算结束了。

为什么需要session?

session呢???session不是经常和cookie一起使用的吗?
上面这种设置cookie的方法存在巨大的安全隐患,就是user_id=1这种结构太简单了,我完全可以自己篡改!(虽然说加上HttpOnly可以防止用户操作cookie,但是有时候可能后端程序员不太小心忘记加上了,或者有时候确实需要前端来操作cookie不能加上)
我只要在浏览器控制台把我的cookie改为:user_id=2,那我不就等于登录了别人的帐号了吗?
为了防止篡改cookie情况的出现,session就登场了

  1. 服务器在后台新建一个session.json的文件。
  2. 服务器在发送cookie的时候,不会再发送user_id了(过于简单,容易被篡改),而是生成一个随机数random,作为session_id,然后把session_id和user_id存储在x文件里。(如果生成的随机数为0.87564563487561,我的user_id=1,那么会是这么储存:
{{0.87564563487561:{"user_d":1}}

  1. 之后,在发送cookie的时候,就会发送session_id,而不是user_id
response.setHeader('Set-Cookie',`session_id=${random};HttpOnly`)

由于session_id是随机的。而且很长,所以难以被篡改。

  1. 之后我发送请求时,我就会带上我的session_id。服务器收到我的请求后,会从session.json里面查找对应的session_id对应的user_id,然后再根据我的user_id在user.json文件里面查找我的信息,进而返回不同的响应。

  2. 因此有了session这一层的保护,cookie就会变得更加安全。


    一般来说回答到这里,cookie与session的基本原理就可以讲清了。但是还可以再为自己加分

手写前端获取对应cookie的值的函数

 function getCookie(cookieName) {
            const strCookie = document.cookie
            const arrayCookie = strCookie.split(';')
            let targetCookie
            try { targetCookie = arrayCookie.filter((cookie) => cookie.indexOf(cookieName + '=') >= 0)[0] }
            catch (error) { }
            if (targetCookie) {
                const cookieValue = targetCookie.split('=')[1]
                return cookieValue
            } else {
                return undefined
            }
        }


点击可参考注册与登录的服务器代码
clnoe后在命令行输入下面代码可运行。

node server.js 9000

你可能感兴趣的:(cookie和session的看法)