在大部分项目中,但凡涉及到登录注册这些功能都会跟 Cookie 有着不可分割的关系。
本文需要有一些 HTTP 基础知识,可以查看博客中 《HTTP简介》进行了解。好了进入正题,这次关于 Cookie 的相关内容我会结合着登录注册一起记录,并且所有代码都是基于 《 AJAX 》。
一、Cookie 是什么的?
它是一个数据包,每次访问网站的时候浏览器都会将该网站的 Cookie 发回给网站服务器,同时网站也可以随意更改你机器上对应的 Cookie 。 Cookie 不是只有一个,而是一个网站一个,所以把它比喻成网络身份证的说法是不准确的。它不是你在网络中的唯一标识,只是你在某个网站的唯一标识。
1、Cookie 的特点
- 服务器通过
Set-Cookie响应头设置Cookie - 浏览器得到
Cookie后,每次请求都要带上Cookie - 服务器读取
Cookie就知道登录用户的信息
但是此时 Cookie 存在几个问题:
- 在
Chrome上登录后得到的Cookie用Safari访问,并不会带上Cookie信息 Cookie存储在WindowsC 盘下的一个文件中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和RequestAPIs 进行访问,以防跨站脚本攻击(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 值来确认前台页面显示的信息。
本文纯属原创,转载请注明出处。