乐趣区

以登录注册理解Cookie的作用过程

这篇文章是前一篇文章 (Cookie 理论知识) 的实践性理解
完整代码:
完整代码
Cookie 在注册登录时的作用过程:
注册
注册时把账号密码写入数据库
登录
第一次登录时服务器给浏览器发送 Cookie.
后台的登录路由代码(nodejs):
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
这时候我们查看响应:

发现响应头已经设置 cookie.

然后跳转到主页,这时候我们查看跳转到主页的请求:

发现跳转到主页的请求头中包含 cookie 字段(以后访问这个域名都会带着这个 Cookie)! 所以,就像上篇文章说的:
如果服务器给了浏览器一个 setcookie 的响应头,那么这个浏览器以后所有的请求,只要是相同的源(即就是上次给我发送 Cookie 的那个域名, 域名和端口相同),那就么就会把当时服务器发给这个浏览器的 Cookie 带着
以后,浏览器一旦访问这个路径,浏览器就会附上这段 Cookie 发送给服务器
即: 第一次请求, 服务器为浏览器设置 Cookie. 下次请求, 浏览器带上 Cookie, 发送给服务器. 第一次登录的时候, 服务器给浏览器的响应设置一个 Cookie,set-cookies:user_email=1@mtt.com, 然后当浏览器下次进行请求的时候, 发现 Cookie 中有名为 User_email 的 Cookie, 而且我发送请求的域名还是上次发给我带 Cookie 的响应的那个域名.
那么就无需再次登录了. 相当于服务器给浏览器发了进入门票, 下次或下下次浏览器在进入服务器的时候给服务器看票就可以了
后台读取 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 在登录的时候的特点
我们得到 Cookie 的特点:

第一次登录的时候, 服务器通过 Set-Cookie 响应头设置 Cookie, 然后以响应的形式发给浏览器
浏览器得到 响应中 Cookie 之后,之后每次请求这个域名都要带上这个 Cookie
之后服务器读取当时自己设置的 Cookie 就知道登录用户的信息(email)

几个关于 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 改不了, 也无法获取), 具体语法看 MDN4.Cookie 有效期吗?默认有效期 20 分钟左右,不同浏览器策略不同(如果浏览器一直开着, 那么 Cookie 不会被删除. 如果关闭浏览器, 那么浏览器为了安全考虑,20 分钟左右后可能会删除 Cookie. 这也取决于服务器如何设置 Cookie 的有效期) 后端可以强制设置有效期,具体语法看 MDNCookie 遵守同源策略吗?也有,不过跟 AJAX 的同源策略稍微有些不同。当请求 qq.com 下的资源时,浏览器会默认带上 qq.com 对应的 Cookie,不会带上 baidu.com 对应的 Cookie 当请求 v.qq.com 下的资源时,浏览器不仅会带上 v.qq.com 的 Cookie,还会带上 qq.com 的 Cookie 另外 Cookie 还可以根据路径做限制,请自行了解,这个功能用得比较少。
需要注意的细节问题
为什么前后端都要进行表单验证?
前后端都要验证邮箱格式是否正确,账号密码格式是否正确,两次提交的密码是否相同等。因为黑客可以绕过前端的 js 验证流程,例如黑客可以直接使用 curl 进行请求的发送,直接与后台服务器进行交互。如图:

所以后台也需要进行表单验证。
Cookie 如何手动关闭

翻译
cookie:曲奇饼 cache-control:缓存控制

退出移动版