在大部分项目中,但凡涉及到登录注册这些功能都会跟 Cookie 有着不可分割的关系。
本文需要有一些 HTTP 基础知识,可以查看博客中 《HTTP简介》进行了解。好了进入正题,这次关于 Cookie 的相关内容我会结合着登录注册一起记录,并且所有代码都是基于 《 AJAX 》。
一、Cookie 是什么的?
它是一个数据包,每次访问网站的时候浏览器都会将该网站的 Cookie 发回给网站服务器,同时网站也可以随意更改你机器上对应的 Cookie 。 Cookie 不是只有一个,而是一个网站一个,所以把它比喻成网络身份证的说法是不准确的。它不是你在网络中的唯一标识,只是你在某个网站的唯一标识。
1、Cookie 的特点
- 服务器通过
Set-Cookie
响应头设置Cookie
- 浏览器得到
Cookie
后,每次请求都要带上Cookie
- 服务器读取
Cookie
就知道登录用户的信息
但是此时 Cookie
存在几个问题:
- 在
Chrome
上登录后得到的Cookie
用Safari
访问,并不会带上Cookie
信息 Cookie
存储在Windows
C 盘下的一个文件中Cookie
能做假Cookie
有有效期,默认有效期为 20 分钟,但是后端可以强制设置有效期,通过设置Expires
和Max-age
,HttpOnly
可以设置是否可以通过 JS 操作,Secure
可以用来设置是否必须使用https
协议
2、Cookie
的设置
HTTP
常设置 Cookie
的几个值主要有 Expires
、 Max-Age
、 Domain
、 Path
、 Secure
、 HttpOnly
。简要释义:
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
失效前需要经过的秒数。一位或者多位非零数字。一些老的浏览器不支持。需要说明的是,如果Expires
和Max-age
同时存在,那么Max-age
优先级更高。设置方法同上。Domain
:可选。指定Cookie
送达的主机名。如果未指定,则默认为当前文档访问地址中的主机部分,不包含子域名。Path
:可选。指定一个URL
路径,这个路径必须出现在要请求的资源的路径中才可以发送Cookie
首部。字符%x2F("/")
可以解释为文件目录分隔符,此目录的下级目录也满足匹配的条件,如path=/docs
,那么/docs
、/docs/Web
、/docs/Web/HTTP
都满足匹配条件。Secure
:可选。一个带有安全属性的Cookie
只有在请求使用SSL
和HTTPS
协议的时候才会被发送到服务器。然而,保密或敏感信息永远不要放在HTTP Cookie
中存储或者传输,因为整个机制从本质上来说都是不安全的。HttpOnly
:可选。设置了HttpOnly
属性的cookie
不能使用JavaScript
经由Document.cookie
属性、XMLHttpRequest
和Request
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
5let 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
2res.setHeader('Content-Type','text/html;utf-8');
res.setHeader('Set-Cookie',[`user_mail=${email}`,'HttpOnly'])
登录成功后,在后端根据请求是带上的 cookie 信息,本次代码中带上的是邮箱信息,据此去查询数据库中用户密码信息,如果存在,那么可以根据 cookie 值来确认前台页面显示的信息。
本文纯属原创,转载请注明出处。