cookie&session

Cookie

在web应用中,多个请求之间共享“用户会话”是非常必要的,但http协议是无状态的,而cookie则可以处理。

  · 服务端向客户端发送cookie

  · 客户端的浏览器把cookie保存

  · 然后在每次请求浏览器都会将cookie发送到服务端

在HTML文档被发送之前,web服务器通过传送HTTP包文头中的Set-Cookie消息把一个cookie发送到用户的浏览器中。其中比较重要的属性有:

  · name=value:键值对,可以设置要保存的key/value,注意这里的name不能和其他属性项的名字一样

  · Expires:过期时间(秒),在设置的某个时间点后该cookie就会失效

  · maxAge:最大失效时间(毫秒),设置在多少后失效

  · secure:当secure为true时,cookie在http中是无效的,在https中才有效

  · path:表示cookie影响到的路径,如path=/。如果路径不能匹配时,浏览器则不发送cookie

  · httpOnly:是微软对cookie做的扩展。如果在cookie中设置了该属性,则通过程序(JS脚本、applet等)将无法读取到cookie信息,防止XSS攻击产生。

nodejs使用response.writeHead向客户端发送cookie。使用writeHead只能发送一次头部,即只能调用一次,且不能与response.render共存,否则会报错。

还可以使用response.setHeader

var http = require('http');
http.createServer(function(req,res){
  if(req.url == '/write'){
      //响应头 实体头 扩展头自定义头
      var time = new Date(new Date().getTime() + 10*1000).toGMTString();
      res.writeHead(200,{
          'Set-Cookie':'age=6; path=/; Expires='+time
      });
      res.end('ok');
  }else if(req.url == '/read'){
      console.log(req.headers.cookie);
      //第二次
    res.end('hello');
  }
}).listen(8080);

express中使用cookie

express在4.x版本之后,管理session和cookie等许多模块都不再直接包含在express中,而是需要单独下载安装相应模块。

cookieParser安装: npm install cookie-parser

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

var app = express();
app.use(cookieParser());
// req.headers.cookie= name=zfpx; age=6
app.get('/write', function (req, res) {
    // 默认设置
    //res.cookie('name','zfpx');

    //设置域名 只有再次访问指定域名的时候客户端才会向服务器端发送cookie
    //res.cookie('name','zfpx',{
    //    domain:'.zfpx.cn'.
    //});

    //指定路径.,只有当下次客户端 向服务器发送请求时,如果path=/read1的时候,才会向服务器发送,否则 不发送
   /* res.cookie('name','zfpx',{
        path:'/read1'
    });*/
    //指定有效期
    res.cookie('name','zfpx',{
        expires:new Date(Date.now()+10*1000),
        maxAge:10*1000
    });
    res.end('ok');
});

app.get('/read',function(req,res){
    console.log(req.cookies);
    res.send(req.cookies);
});
app.get('/read1',function(req,res){
    console.log(req.cookies);
    res.send(req.cookies);
});
app.listen(80);

 cookie实现登录逻辑

var express = require('express');
var cookieParser = require('cookie-parser');
var path = require('path');
var bodyParser = require('body-parser');
var app = express();
app.set('view engine','ejs');
app.set('views',path.resolve());
app.use(cookieParser());

function checkLogin(req,res,next){
    if(req.cookies && req.cookies.username){
        next();
    }else{
        res.redirect('/');
    }
}

//进入登录页
app.get('/',function(req,res){
 res.render('login',{});
});


// 登录
app.get('/login',function(req,res){
   var username = req.query.username;
   res.cookie('username',username);
    //重定向,让客户端重向新求参数指定的路径
   res.redirect('/user');
});
//用户主页
app.get('/user',checkLogin,function(req,res){
    res.send(req.cookies.username);
});

app.listen(80);

session

session是一种记录客户端状态的机制,不同的是cookie保存在客户端浏览器中,而session保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问时只需要从该session中查找该客户的状态就可以了。

如果说cookie机制是通过检查客户身上的通行证来确定客户身份的话,那么session几只就是通过检查服务器上的客户明细表来确认客户身份。session相当于程序在服务器上建立了一份客户档案,客户来访的时候只需要查询客户档案表就可以了。

两者的区别:

  · cookie数据存放在客户的浏览器上,session数据放在服务器上。

  · cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗,而session就相对更安全

  · session会在一定时间内保存在服务器上,当访问增多,会比较占用服务器的性能,而cookie就相对可以减轻服务器的性能压力

  · 单个cookie保存的数据不能超过4k,很多浏览器都限制一个站点最多保存20个cookie。

tips:将登陆信息等重要信息存放在session,其他信息如果需要保留,可以放在cookie中。

express中使用session

与cookie一样需要单独的安装和引用模块   npm install express-session

主要方法就是session(options),其中options主要有:

  · name:设置cookie中,保存session的字段名称,默认为connect.id

  · store:session的存储方式,默认存放在内存中,也可以使用redis、mongodb等。express生态中都有相应模块的支持

  · secret:通过设置的secret字符串,来计算hash值并放在cookie中,使产生的signedCookie防篡改

  · cookie:设置存放session id的cookie的相关选项,默认为{default:{path:'/',httpOnly:true,secure:false,maxAge:null}}

  · genid:产生一个新的session_id时,所使用的函数,默认使用uid2这个npm包

  · rolling:每个请求都重新设置一个cookie,默认为false

  · resave:即使session没有被修改,也保存session值,默认为true

  · saveUninitialized:保存新创建但未修改的session

var express = require('express');
var session = require('express-session');
var app = express();
var sessions = {};
app.use(session({
    secret: 'zf', //secret的值建议使用随机字符串
    cookie: {maxAge: 60 * 1000 * 30}, // 过期时间(毫秒)
    resave:true,//每次响应结束 的时候 都重新保存session
    saveUninitialized:true //保存未初始化的session
}));
app.get('/', function (req, res) {
    if (req.session.sign) {//检查用户是否已经登录
        console.log(req.session);//打印session的值
        res.send('welcome <strong>' + req.session.name + '</strong>, 欢迎你再次登录');
    } else {
        //因为session是借用cookie实现的,所以当设置session的时候,会自动设置cookie。第一次访问的时候,会生成一个sid
        req.session.sign = true;
        req.session.name = 'zf';
        res.send('欢迎登陆!');
    }
});
app.listen(80);

 首先引入express-sesion,然后使用session方法返回的中间件,执行完该中间件后request就会有一个session属性,其值为对象。第一次访问“/”时session没有sign值,则会先给sign赋值。

由于使用session时会给cookie存一个sessionId(即加密后的connect.id),所以session是依赖于cookie的。

session的原理是第一次访问的时候,随机生成一个sid并生成一个sid对应的对象,然后把这个sid发送到浏览器端。下次客户端把sid带回服务器,从服务器上找到这个sid对应的对象就可以了。

原理如下

var express = require('express');
var app = express();
app.use(require('cookie-parser')());
//放在服务器端的客户明细表
var session = {};
app.get('/', function (req, res) {
    //取出cookie中的sid
  var sid = req.cookies.sid;
    //如果有值的话就表示访问过了
    if(sid){
        //从服务器的session对象中取出当前客户端在服务器对应的session
        var currentSession = session[sid];
        //赋值
        currentSession.mny = currentSession.mny-10;
        res.send(''+currentSession.mny);
    }else{
        //生成新的sid
        var newSid = Date.now()+''+Math.random();
        session[newSid] = {mny:100};
        //写入到客户端
        res.setHeader('Set-Cookie','sid='+newSid);
        res.send('新朋友');
    }
});
app.listen(80);

 

posted @ 2017-02-22 16:54  叮呤  阅读(363)  评论(0编辑  收藏  举报