Nodejs 学习(四)

本文围绕Server端Node.js展开,介绍了操作Cookie的方法,包括查看、修改、实现登录验证等,还提及Cookie的Http头、有效期设置及防止前端修改的方法。同时指出Cookie和Session使用的局限,引出解决方案Redis,介绍了Redis的安装、使用及Node.js连接Redis的封装工具函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Server端nodejs操作cookie

Cookie、session使用时的局限

redis的使用(nodejs连接redis-封装工具函数)

 

Server端nodejs操作cookie

查看cookie

修改cookie

实现登录验证

1、解析cookie

//解析cookie

    const cookieStr = req.headers.cookie || '';

 

//登录验证测试

    if(method === 'GET'&& path === '/api/user/login-test'){

        if(req.cookie.username){

            return Promise.resolvenew SuccessModel('登陆成功'));

        }else{

            return Promise.resolvenew ErrorModel('登陆失败'));

        }

 

    }

path=/代表cookie生效目录,’/’代表根目录,整个网站都生效

res.setHeader('Set-Cookie',`username=${loginData.username};path=/`)

 

 

Cookie相关的Http头

    有 两个Http头部和Cookie有关:Set-Cookie和Cookie。

    Set-Cookie由服务器发送,它包含在响应请求的头部中。它用于在客户端创建一个Cookie

    Cookie头由客户端发送,包含在HTTP请求的头部中。注意,只有cookie的domain和path与请求的URL匹配才会发送这个cookie。

expires=<date>: 设置cookie的有效期,如果cookie超过date所表示的日期时,cookie将失效。

如果没有设置这个选项,那么cookie将在浏览器关闭时失效。

注意:date是格林威治时间(GMT),使用如下格式表示:

 

 

如何防止前端修改cookie:添加httpoply

httpOnly

res.setHeader('Set-Cookie',`username=${loginData.username};path=/;httpOnly`)

设置完效果

 

前端无法更改

 

问题:拼接cookie时会自动在分号后添加空格

解决:trim()

设置过期时间

expires=${getCookieExpires()

res.setHeader('Set-Cookie',`username=${loginData.username};path=/;httpOnly;expires=${getCookieExpires()}`)

 

 

 

cookie问题

会暴露传递参数

大小限制

如何解决:不传递username,存储userid,server端对应username

解决方案:session,即server端存储客户信息

 

 

 

    //解析session

    let needSetCookie = false;

    let userId = req.cookie.userid

    if(userId){

        if(!SESSION_DATA[userId]){

            SESSION_DATA[userId= {}

        }

    }else{

        needSetCookie = true;

        userId = `${Date.now()}+${Math.random()}`;

        SESSION_DATA[userId= {}

    }

    req.sesssion = SESSION_DATA[userId];

 

 

 

if(needSetCookie){

res.setHeader('Set-Cookie',`userId=${userData.userId};path=/;httpOnly;expires=${getCookieExpires()}`);

                    }

 

 

//登录验证测试

    if(method === 'GET'&& path === '/api/user/login-test'){

        if(req.session.username){

            // res.setHeader('Set-Cookie',`username=${loginData.username};path=/;httpOnly;expires=${getCookieExpires()}`)

            return Promise.resolvenew SuccessModel(

                {session:req.session}

            ));

        }else{

            return Promise.resolvenew ErrorModel('尚未登录'));

        }

    }

 

 

当前代码中使用Session的问题

目前session是js变量,放在nodejs进程内存中

第一,进程内存有限,访问量过大,内存暴增怎么办?(操作系统会限制一个进程的最大可用内存)

第二,正式上线后运行是多进程,进程之间内存无法共享

 

解决方案redis

Webserver最常用的缓存数据库,数据存放在内存中

相比于mysql,访问速度快

但是成本更高,可存储的数据量更小

 

 

Redis安装

教程地址:https://www.runoob.com/redis/redis-install.html

Redis使用


打开一个 cmd 窗口 使用 cd 命令切换目录到 C:\redis 运行:

redis-server.exe redis.windows.conf

这时候另启一个 cmd 窗口,原来的不要关闭,不然就无法访问服务端了。

切换到 redis 目录下运行:

redis-cli.exe -127.0.0.1 -6379

 

设置键值对:

set myKey abc

 

取出键值对:

get myKey

 

删除键值对

del mykey

 

查看所有键

keys *

 

 

redis demo

新建redis-test文件夹

npm i redis --save

 

报错

Error: Redis connection to 127.0.0.1:6739 failed - connect ECONNREFUSED 127.0.0.1:6739

at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1106:14)

 

 

重启解决了……

最终代码

 

// const redis = require('redis');

 

// //创建客户端

// const redisClient = redis.createClient(6739,'127.0.0.1');

// redisClient.on('error',err=>{

//     console.error(err);

 

// });

 

// //测试

// redisClient.set('myname','zhangsan',redis.print);

// redisClient.get('myname',(err,val)=>{

//     if(err){

//         console.error(err);

//         return

//     }

//     console.log('val',val);

//     //退出

//     redisClient.quit();

// });

 

const redis = require("redis");

 

// //创建客户端

const redisClient = redis.createClient(6379,'127.0.0.1');

 

redisClient.on("error",(err)=>{

    console.error(err);

})

redisClient.set('myname','zhangsan',redis.print);

redisClient.get('myname',(err,val)=>{

    if(err){

        console.error(4);

        console.error(err);

        return

    }

    console.log('val',val);

    redisClient.quit();

});

 

控制台打印

 

 

Nodejs连接redis-封装工具函数

配置连接redis参数

 

 

这段代码逻辑很好

const redis =require("redis");

const {REDIS_CONF= require("../conf/db");

 

//创建客服端

const redisClient = redis.createClient(REDIS_CONF.port,REDIS_CONF.host);

 

redisClient.on("error",(err)=>{

    console.error(err);

});

 

function set(key,val){

    if(typeof val === 'object'){

        val = JSON.stringify(val);

    }

    redisClient.set(key,val,redis.print);

}

function get(key){

   

    const promise = new Promise((resolve,reject)=>{

        redisClient.get(key,(err,val)=>{

            if(err){

                reject(err)

                return

            }

            // resolve(val)

            if(val === null){

                resolve(null)

                return

            }

            try{

                resolve(

                    JSON.parse(val)

                )

            }catch(ex){

                resolve(val)

            }

        });

    })

    return promise

}

 

module.exports = {

    set,

    get

}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值