Cookie 与登录注册

在大部分项目中,但凡涉及到登录注册这些功能都会跟 Cookie 有着不可分割的关系。

本文需要有一些 HTTP 基础知识,可以查看博客中 《HTTP简介》进行了解。好了进入正题,这次关于 Cookie 的相关内容我会结合着登录注册一起记录,并且所有代码都是基于 《 AJAX 》

一、Cookie 是什么的?

它是一个数据包,每次访问网站的时候浏览器都会将该网站的 Cookie 发回给网站服务器,同时网站也可以随意更改你机器上对应的 Cookie 。 Cookie 不是只有一个,而是一个网站一个,所以把它比喻成网络身份证的说法是不准确的。它不是你在网络中的唯一标识,只是你在某个网站的唯一标识。

1、Cookie 的特点

  • 服务器通过 Set-Cookie 响应头设置 Cookie
  • 浏览器得到 Cookie 后,每次请求都要带上 Cookie
  • 服务器读取 Cookie 就知道登录用户的信息

但是此时 Cookie 存在几个问题:

  • Chrome 上登录后得到的 CookieSafari 访问,并不会带上 Cookie 信息
  • Cookie 存储在 Windows C 盘下的一个文件中
  • Cookie 能做假
  • Cookie 有有效期,默认有效期为 20 分钟,但是后端可以强制设置有效期,通过设置 ExpiresMax-ageHttpOnly 可以设置是否可以通过 JS 操作,Secure 可以用来设置是否必须使用 https 协议

2、Cookie 的设置

HTTP 常设置 Cookie 的几个值主要有 ExpiresMax-AgeDomainPathSecureHttpOnly 。简要释义:

  • Expires : 可选。为 Cookie 的最长有效时间,形式为符合 HTTP-date 规范的时间戳。默认为 20 分钟。如果没有设置这个属性,那么在关闭客户端时,Cookie 会失效。不过但部分 Web 浏览器支持会话恢复功能,即关闭了浏览器后再次打开 Cookie 仍旧会恢复。在 HTTP 请求中设置这个值的规范写法为:
1
res.setHeaders('set-Cookie',['login_nam=xxxxx','Expires=Wed, 04-Jul-2018 04:41:45 GMT'])
  • Max-age:可选。Cookie 失效前需要经过的秒数。一位或者多位非零数字。一些老的浏览器不支持。需要说明的是,如果 ExpiresMax-age 同时存在,那么 Max-age 优先级更高。设置方法同上。
  • Domain:可选。指定 Cookie 送达的主机名。如果未指定,则默认为当前文档访问地址中的主机部分,不包含子域名。
  • Path :可选。指定一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。字符 %x2F("/") 可以解释为文件目录分隔符,此目录的下级目录也满足匹配的条件,如 path=/docs ,那么 /docs/docs/Web/docs/Web/HTTP 都满足匹配条件。
  • Secure:可选。一个带有安全属性的 Cookie 只有在请求使用 SSLHTTPS 协议的时候才会被发送到服务器。然而,保密或敏感信息永远不要放在 HTTP Cookie 中存储或者传输,因为整个机制从本质上来说都是不安全的。
  • HttpOnly:可选。设置了 HttpOnly 属性的 cookie 不能使用 JavaScript 经由 Document.cookie 属性、XMLHttpRequestRequest APIs 进行访问,以防跨站脚本攻击(XSS)。

二、准备页面

引入了 bootstrap 和 jquery 的 cdn ,在两个的基础上做了登录和注册页面。同时改了 server.js 文件。具体看代码吧,这个登录注册的验证代码看看就明白了。server.js

三、关于登录注册页面中的问题

1、同一个页同一请求不同方式

启动 serve.js 后,在浏览器中打开 http://localhost:8888/login ,此时进入登录页面。输入用户信息,点击登录时我们可以发现,登录走的路径也是 /login ,进入登录页请求的路径也是 /login ,二者的不同在于进入页面的资源请求使用的是默认的 GET 方式,点击登录按钮的请求方式为 POST 方式。根据请求方式不同,在 server.js 中做不同的处理。注册页面同理。

2、url 解码

在将用户邮箱、密码信息发送到服务端的时候,会将一些特殊字符进行转码,如 @ 字符会自动转成 %40,如果不进行转码处理的话,在验证用户邮箱的时候必然会出错。使用 decodeURIComponent(val) 可对 encodeURIComponent() 函数编码的 URI 进行解码。

3、读取/存储用户信息

在读取存储用户信息,我在当前目录下创建了 ./db/users 文件,文件内初始内容为一个空数组。读写文件内容的方法为:

1
2
3
4
5
let str = fs.readFileSync('./db/users'.'uft-8');    //读取文件内容,读出来的为字符串
let users = JSON.parse(str); //将字符串转成数组对象
let user = {'email':'xxx@123.com','password','12345'}; //根据请求发送的数据将新用户的数据转成对象,此步不详细解释
users.push(user); //将新用户数据push到数组中
fs.writeFileSync('./db/users',JSON.stringify(users)); //将更新后的users信息转成字符串写入文件中

四、Cookie 的使用

在用户登录成功后,可将 cookie 信息通过 Set-Cookie 发送给前台页面。如果邮箱密码验证无误的话,设置 cookie 值和设置相应头的方式一样:

1
2
res.setHeader('Content-Type','text/html;utf-8');
res.setHeader('Set-Cookie',[`user_mail=${email}`,'HttpOnly'])

登录成功后,在后端根据请求是带上的 cookie 信息,本次代码中带上的是邮箱信息,据此去查询数据库中用户密码信息,如果存在,那么可以根据 cookie 值来确认前台页面显示的信息。


本文纯属原创,转载请注明出处。