cookie和session

460 阅读2分钟

cookie session localStorage sessionStorage区别

cookie:

由于http请求是无状态的,我们需要识别请求是身份,因此有了cookie,cookie用来识别身份;浏览器,服务器都可以设置cookie; cookie不要设置的太大,可能造成页面白屏,浪费流量等(可以根据路径合理设置cookie,定期删除cookie);cookie最终是被存放到客户端的,所以cookie最大的问题是不安全。

session:

cookie存在客户端是不安全的,为了解决cookie的不安全问题,诞生了session, session是存放在服务器端的,session是基于cookie实现的

localStorage:

浏览器本地存储,可以存放一些网路资源,关闭网页后,下次依然可以使用

sessionStorage:

用于页面之间传值,页面关闭后就会立即销毁

cookie

  • name: 用户设置的健
  • value: 用户设置的值
  • domain: 限制域名,默认是当前域名
  • path: 限制设置cookie的路径(基本不用),减少cookie传入
  • maxAge/Expires:maxAge多少秒后,Expires精确的某个时间,都表示cookie存活多久
  • httpOnly: 设置为true,不能通过代码去修改cookie, 但是还是可以在浏览器cookie中修改的
//设置cookie
res.setHeader('Set-Cookie', ['name=zs; max-age=10', 'age=18; httpOnly=true']);

//获取cookie
req.headers('cookie')

将cookie设置和修改改为更简单方式

在开发中使用原生设置与获取cookie是比较麻烦的,我们更希望通过 setCookie 来设置一个cookie, getCookie 来获取一个cookie;

const http = require('http');
const querystring = require('querystring');

const server = http.createServer((req, res) => {
    //获取cookie
    req.getCookie = (key) => {
        let cookieObj = querystring.parse(req.headers['cookie'], '; ');
        if (cookieObj && cookieObj[key]) {
            return cookieObj[key]
        } else {
            return ''
        }
    }

    //设置cookie
    let cookies = [];
    res.setCookie = (key, value, options) => {
        let optArgs = [];
        if (options.maxAge) {
            optArgs.push(`max-age=${options.maxAge}`)
        }
        if (options.httpOnly) {
            optArgs.push(`httpOnly=${options.httpOnly}`)
        }
        if (options.path) {
            optArgs.push(`path=${options.path}`)
        }
        if (options.domain) {
            optArgs.push(`domain=${options.domain}`)
        }
        if (options.Expires) {
            optArgs.push(`Expires=${options.Expires}`)
        }
        const cookieValue = `${key}=${value}`;
        cookies.push(`${cookieValue}; ${optArgs.join('; ')}`);
        console.log(cookies)
        res.setHeader('Set-Cookie', cookies)
    }

    if (req.url == '/read') {
        const value = req.getCookie('name');
        res.end(value);
    } else if (req.url === '/write') {
        res.setCookie('name', 'zs', {
            maxAge: 30
        });
        res.setCookie('age', 18, {
            httpOnly: true
        });
        res.end('write ok');
    } else {
        res.statusCode = 404;
        res.end('Not Found');
    }

});

server.listen(3000, () => {
    console.log(`start sever success`)
})

cookie加盐

const http = require('http');
const querystring = require('querystring');
const crypto = require('crypto');
//盐值,这里的值只是一个模拟,正常情况下我们会通过opensll生产一个1028字节的密钥
const key = 'hh';
//给值加盐
function signed(value) {
    //需要将value.toString(),防止用户设置的是一个数值类型的
    return crypto.createHmac('sha256', key).update(value.toString()).digest('base64');
}
const server = http.createServer((req, res) => {
    //获取cookie
    req.getCookie = (key, options = {}) => {
        let cookieObj = querystring.parse(req.headers['cookie'], '; ');
        console.log(cookieObj)
        //是否需要校验签名
        if (options.signed) {
            const [value, sign] = cookieObj[key].split('.');
            return signed(value) == sign ? value : '';
        } else {
            return cookieObj && cookieObj[key] ? cookieObj[key].split('.')[0] : ''
        }
    }

    //设置cookie
    let cookies = [];
    res.setCookie = (key, value, options) => {
        let optArgs = [];
        if (options.maxAge) {
            optArgs.push(`max-age=${options.maxAge}`)
        }
        if (options.httpOnly) {
            optArgs.push(`httpOnly=${options.httpOnly}`)
        }
        if (options.path) {
            optArgs.push(`path=${options.path}`)
        }
        if (options.domain) {
            optArgs.push(`domain=${options.domain}`)
        }
        if (options.Expires) {
            optArgs.push(`Expires=${options.Expires}`)
        }
        //将值加盐
        if (options.signed) {
            value = `${value}.${signed(value)}`;
        }
        const cookieValue = `${key}=${value}`;
        cookies.push(`${cookieValue}; ${optArgs.join('; ')}`);
        res.setHeader('Set-Cookie', cookies)
    }

    if (req.url == '/read') {
        const value = req.getCookie('age', {
            signed: true
        });
        console.log(value)
        res.end(value);
    } else if (req.url === '/write') {
        res.setCookie('name', 'zs', {
            maxAge: 30
        });
        res.setCookie('age', 18, {
            httpOnly: true,
            signed: true
        });
        res.end('write ok');
    } else {
        res.statusCode = 404;
        res.end('Not Found');
    }

});

server.listen(3000, () => {
    console.log(`start sever success`)
})

session

cookie是放在客户端的,是不安全的,session是房子服务器的

const http = require('http');
const querystring = require('querystring');
const crypto = require('crypto');
const uuid = require('uuid');
const key = 'hh';
const CardName = 'connect.sid';
const session = {};

function signed(val) {
    return crypto.createHmac('sha256', key).update(val).digest('base64');
}
const server = http.createServer((req, res) => {
    req.getCookie = function(key, options) {
        const cookie = req.headers['cookie'];
        const cookieObj = querystring.parse(cookie);
        if (options.signed) {
            let [value, sign] = cookieObj[key].split('.');
            return signed(value) === sign ? value : '';
        } else {
            return cookieObj[key] ? cookieObj[key].split('.')[0] : '';
        }
    }

    let cookies = [];
    res.setCookie = function(key, value, options) {
        let optArgs = [];
        if (options.MaxAge) {
            optArgs.push(`max-age=${options.MaxAge}`);
        }
        if (optArgs.path) {
            optArgs.push(`path=${optArgs.path}`);
        }
        if (optArgs.httpOnly) {
            optArgs.push(`httpOnly=${optArgs.httpOnly}`);
        }
        if (optArgs.domain) {
            optArgs.push(`domain=${optArgs.domain}`);
        }
        if (optArgs.Expires) {
            optArgs.push(`Expires=${optArgs.Expires}`);
        }
        const cookieVal = `${key}=${value}`;
        cookies.push(`${cookieVal}; ${optArgs.join('; ')}`);
        res.setHeader('Set-Cookie', cookies);
    }

    if (req.url === '/cut') {
        let cardId = rq.getCookie(CardName);
        //服务器重启,session就会被清空
        if (cardId && session[cardId]) {
            session[cardId].mmy = -10;
            res.end(`${session[cardId].mmy} money`);
        } else { //第一次,需要办卡
            const cardId = uuid.v4();
            session[cardId] = {
                mmy: 500
            };
            res.setCookie(CardName, cardId, {
                httpOnly: true
            });
        }
    } else {
        res.end();
    }

});

server.listen(3000, () => {
    console.log('start sever success');
})