计算机网络IT课程分享程序员

cookie的工作原理

2017-08-24  本文已影响228人  蓝桥云课

说明:文章所有内容均节选自实验楼教程【实现express框架中的session中间件】,该教程总共6节内容,文章选自第一节内容,剩下的5节内容为:

  • 开发一个 session 模块 exSession
  • 基于 exSession 模块的两个例子程序
  • 使用 express 中的 session 中间件
  • 开发一个 session 中间件 exSesson
  • 基于 exSession 中间件开发两个例子程序
    如果你想要学习全部内容,点击教程【实现express框架中的session中间件】即可,详细的步骤说明和开发代码,带你实现一个session中间件,从而透彻理解session的工作机制。

一、实验介绍

1.1 实验内容

对初学者来说,cookie 与 session 的工作机制是较难理解的知识点。express 框架提供了 session 中间件 express-session,实现了session 机制。本课学习开发一个接口与 express-session 相同的中间件 exSession,从而透彻理解 session 的工作机制。

文章首先介绍 cookie 的相关理论知识,然后通过具体的例子,观察浏览器的发出的 http 头部信息和接收的 http 头部信息,从而理解 cookie 的工作原理。

1.2 实验知识点

1.3 实验环境

1.4 代码获取

可通过以下命令下载源码参考对比进行学习

$ wget http://labfile.oss.aliyuncs.com/courses/901/node-session-examples.tgz

二、cookie 的工作原理

2.1 cookie 简介

Cookie 技术产生源于 HTTP 协议在互联网上的急速发展。随着互联网的快速发展,人们需要更复杂的互联网交互活动,就必须同服务器保持活动状态。为了适应用户的需求,技术上推出了各种保持Web浏览状态的手段,其中就包括了Cookie技术。

举个例子,用户 linuxmooc 在没有登陆 baidu 时,baidu 首页的界面如下图所示:


baidu0

用户 linuxmooc 登陆 baidu 页面后,可以看到页面的右上角显示了他的名称 linuxmooc,如下图所示:


baidu1

用户 linuxmooc 在没有登陆 baidu 时,访问的网页 url 是http://www.baidu.com;在登陆 baidu 后,访问的网页 url 仍然是http://www.baidu.com,但是这两次访问呈现的结果不相同,登陆前没有显示用户名,登陆后显示了用户名。问题是:服务端是如何区分这两次请求的?

服务端采用这样的机制区分这两次请求的,如下图所示:


int
  1. 用户 linuxmooc 登陆 baidu
  2. baidu 服务端会生成一个用户 ID
  3. 然后,服务端将这个用户 ID 发送给浏览器
  4. 浏览器收到这个用户 ID 后,会将这个用户ID保存在用户本地终端
  5. 浏览器再次访问 baidu 站点时,浏览器会将保存在本地的用户ID再次发给 baidu 服务端

服务端收到浏览器发送的用户 ID 后,就知道此次请求来自于一个已经登陆的用户。在以上的交互过程中,保存在客户端的用户 ID 就被称为 cookie

2.2 cookie 定义

网站常常需要记录访问者的一些一些基本信息,例如如身份识别号码、密码、用户在 Web 站点购物的方式或用户访问该站点的次数。 网站为了辨别用户身份、进行 session 跟踪需要把数据储存在用户本地终端上,这些数据被称为 cookie。

2.3 服务端发送 cookie

通过设置 HTTP 的 Set-Cookie 消息头,Web 服务器可以指定存储一个 cookie。Set-Cookie 消息的格式如下面所示,括号中的部分都是可选的:

Set-Cookie:value [ ;expires=date][ ;domain=domain][ ;path=path][ ;secure]

消息头的第一部分,value 部分,通常是一个 name=value 格式的字符串。服务端向客户端发送的 HTTP 响应中设置 HTTP 的 Set-Cookie 消息头,一个具体的例子如下:

Connection:keep-alive
Content-Type:text/plain
Date:Fri, 14 Jul 2017 10:49:23 GMT
Set-Cookie:user=ZhangSan
Transfer-Encoding:chunked

在这个例子中,服务端向客户端发送的 Http 消息头中,设置了 'Set-Cookie:user=ZhangSan',客户端浏览器将接受到字符串 'user=ZhangSan' 作为 cookie。

2.4 客户端发送 cookie

当一个 cookie 存在,并且条件允许的话,该 cookie 会在接下来的每个请求中被发送至服务器。cookie 的值被存储在名为 Cookie 的 HTTP 消息头中,并且只包含了 cookie 的值,其它的选项全部被去除。

客户端向服务端发送的 HTTP 请求中设置 Cookie 消息头,一个具体的例子如下:

Connection:keep-alive
Cookie:user=ZhangSan
Host:localhost:8080
User-Agent:Mozilla/5.0 AppleWebKit/537.36 Chrome Safari

在这个例子中,客户端向服务端发送的 Http 消息头中,设置了 'Cookie:user=ZhangSan',服务端接受到字符串 'user=ZhangSan' 作为 cookie,从而确认此次请求对应的用户。

三 实验步骤

3.1 通过 node.js 的原生接口访问 cookie

3.1.1 功能说明

编写一个服务程序 ex0,该服务程序提供三个 url

3.1.2 项目文件结构

ex0/
└── main.js

项目文件位于 ex0 目录下,只有一个源文件 main.js。

3.1.3 初始化项目

$ mkdir ex0
$ cd ex0

3.1.4 创建 main.js 的框架

var http = require('http');
http.createServer(function(req, res) {
    var url = req.url;

    if (url.startsWith('/set')) {
        // 设置Http的Set-Cookie消息头,将Cookie保存到客户端
    }

    if (url.startsWith('/show')) {
        // 将客户端发送的Cookie打印输出
    }

    if (url.startsWith('/del')) {
        // 设置Http的Set-Cookie消息头,将Cookie从客户端删除
    }
}).listen(8080);

3.1.5 实现 set 路由,在 main.js 中添加如下代码

    if (url.startsWith('/set')) {
        res.writeHead(200, {
            'Content-Type': 'text/plain',
            'Set-Cookie': 'user=ZhangSan'
        });
        res.write('Set-Cookie');
        res.end();
    }

3.1.6 实现 show 路由,在 main.js 中添加如下代码

    if (url.startsWith('/show')) {
        var cookie = req.headers.cookie; 
        res.writeHead(200, {
            'Content-Type': 'text/plain'
        });
        res.write('Show-Cookie: ' + cookie);
        res.end();
    }

3.1.7 实现 del 路由,在 main.js 中添加如下代码

    if (url.startsWith('/del')) {
        res.writeHead(200, {
            'Content-Type': 'text/plain',
            'Set-Cookie': 'user=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
        });
        res.write('Del-Cookie');
        res.end();
    }

3.1.8 测试程序 ex0

3.2 通过 cookie-parser 中间件访问 cookie

3.2.1 功能说明

编写一个服务程序 ex1,提供三个 url

该服务程序 ex1 的功能与 ex0 相同,ex1 使用 express 框架的 cookie-parser 中间件去访问 cookie。cookie-parser 能够分析 cookie 字符串,提取对应的 name 和 value,从而简化对 cookie 的访问。

3.2.2 项目文件结构

ex1
├── main.js
└── package.json

项目文件位于 ex1 目录下,源文件 main.js 提供程序的主要功能。

3.2.3 初始化项目,创建项目目录

$ mkdir ex1
$ cd ex1

3.2.4 安装所需的 node.js 模块:express 框架和 cookie-parser 中间件

$ npm init
$ npm install --save express
$ npm install --save cookie-parser

3.2.5 创建 main.js 的框架

var express = require('express');
var cookieParser = require('cookie-parser');
var app = express();
app.use(cookieParser());

app.get('/show', function(req, res) {
    // 将客户端发送的Cookie打印输出
});

app.get('/set', function(req, res) {
    // 设置Http的Set-Cookie消息头,将Cookie保存到客户端
});

app.get('/del', function(req, res) {
    // 设置Http的Set-Cookie消息头,将Cookie从客户端删除
});

app.listen(8080);

3.2.6 实现 set 路由,在 main.js 中添加如下代码

app.get('/set', function(req, res) {
    res.cookie('user', 'ZhangSan');
    res.send('<h1>Set-Cookie</h1>');
});

3.2.7 实现 show 路由,在 main.js 中添加如下代码

app.get('/show', function(req, res) {
    var cookies = req.cookies;
    var text = JSON.stringify(cookies);
    res.send('<h1>Show-Cookie: ' + text + '</h1>');
});

3.2.8 实现 del 路由,在 main.js 中添加如下代码

app.get('/del', function(req, res) {
    res.clearCookie('user');
    res.send('<h1>Del-Cookie</h1>');
});

3.2.9 测试程序 ex1

最后:

上一篇下一篇

猜你喜欢

热点阅读