Cookie
一、cookie 介绍及客户端操作cookie
JS操作cookie, 浏览器中查看cookie:
二、 server 端操作cookie, 实现登录验证
1、server获取cookie的值并解析cookie值
// 解析 cookie
req.cookie = {}
const cookieStr = req.headers.cookie || '' // k1=v1;k2=v2;k3=v3
cookieStr.split(';').forEach(item => {
if (!item) {
return
}
const arr = item.split('=')
const key = arr[0].trim()
const val = arr[1].trim()
req.cookie[key] = val
})
2、server端修改 cookie
res.setCookie('Set-cookie', username='Lisa')
3、实现登录验证
// 登录验证的测试- 如果cookie中有username, 则登录成功
if (method === 'GET' && req.path === '/api/user/login-test') {
if (req.cookie.username) {
return Promise.resolve(
new SuccessModel({
session: req.session
})
)
}
return Promise.resolve(
new ErrorModel('尚未登录')
)
}
4、server端对cookie 做限制
设置完httpOnly后,客户端就没有权限对cookie进行修改了;
res.cookie('Set-cookie', username=${username}; path=/;httpOnly);
5、设置cookie的过期时间
为了安全起见,过一段时间,让用户重新登录一次
// 获取 cookie 的过期时间
const getCookieExpires = () => {
const d = new Date()
d.setTime(d.getTime() + (24 * 60 * 60 * 1000))
console.log('d.toGMTString() is ', d.toGMTString())
return d.toGMTString()
}
然后,server端对cookie设置过期时间:expires = xxx
res.setHeader('Set-Cookie', `userid=${userId}; path=/; httpOnly; expires=${getCookieExpires()}`)
三、cookie总结
总结一: 使用
cookie做登录验证,例如判断cookie中如果有username存在,就便是登录了,这样子会暴漏username,有危险;解决办法:
cookie中存储userid,server端对应username;总结二:
cookie的内存大小只有5KB,可以存储的信息也有限;
Session
一、 session 介绍
// 解析 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.session = SESSION_DATA[userId]
// 登录验证的测试
if (method === 'GET' && req.path === '/api/user/login-test') {
if (req.session.username) {
return Promise.resolve(
new SuccessModel({
session: req.session
})
)
}
return Promise.resolve(
new ErrorModel('尚未登录')
)
}
二、总结
session 解决什么问题,cookie不满足的,session满足; session 如何使用?
如何解决 session 的问题呢?redis;
Redis
Redis是内存数据库, mysql是硬盘数据库(使用B树算法);
1、redis 安装与使用
启动redis :
redis-cli.exe -h 127.0.0.1 -p 6379
使用方法:
设置key: set 变量名 变量值
查看所有的key: keys *
删除指定的 key: del 变量名
2、nodejs 连接 redis 的demo
首先在项目中安装 redis:
npm i redis --save
启动redis服务命令:
redis-server.exe redis.windows.conf
另启一个 cmd 窗口,原来的不要关闭,不然就无法访问服务端
运行:
redis-cli.exe -h 127.0.0.1 -p 6379
const redis = require('redis')
// 创建客户端
const redisClient = redis.createClient(6379, '127.0.0.1')
redisClient.on('error', err => {
console.error(err)
})
// 测试
redisClient.set('myname', 'zhangsan2', redis.print)
redisClient.get('myname', (err, val) => {
if (err) {
console.error(err)
return
}
console.log('val ', val)
// 退出
redisClient.quit()
})
3、nodejs 连接 redis 封装函数
const redis = require('redis')
const {REDIS_CONF} = require('../config/db')
// 创建客户端
const redisClient = redis.createClient(REDIS_CONF)
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
}
if (val == null) {
resolve(null)
return;
}
try {
resolve((JSON.parse(val)))
} catch (ex) {
resolve(val)
}
// 退出
redisClient.quit()
})
})
return promise
}
module.exports = {
set,
get
}