cookie
存储在客户端
优点
- 存储在客户端,不占用服务器资源
缺点
- 只能是字符串格式
- 存量有限
- sessionStorage (有大小限制(约10m)),不会自动发送给服务器
- localStorage (有大小限制(约10m)),不会自动发送给服务器
- 容易被获取
- 容易被篡改
- 容易丢失
session
存储在服务器
优点
- 可以是任何格式
- 存量理论上是无限的
- 数据难以被获取
- 数据难以篡改
- 不容易丢失
缺点
占用服务器资源
uuid universal unique identify 全球唯一id
session原理图
session中间件
- 安装
npm i express-session@1.17.1
- 使用 ```json
const express = require(‘express’); const app = express();//创建一个以express应用,app实际上是一个函数,用于处理请求的函数 const path = require(‘path’); const rootPath = path.resolve(__dirname, ‘../public’); const cookieParser = require(‘cookie-parser’); const cors = require(‘cors’); const session = require(‘express-session’); const whiteApi = [‘http://localhost:3333‘]; // 使用session中间件 app.use(session({ secret: ‘lantong’, // 加密的字符串 name:’sessionId’ // 存储在本地session的名字,默认名字connect.sid })) // 设置cookieParser中间件 app.use(cors({ origin(origin, callback) { console.log(‘origin’, origin) if (whiteApi.includes(origin)) { callback(null, origin); } else { callback(new Error(“not allowed”)); } }, credentials: true })) // 使用跨域中间件
// 设置以后,会自动在req里面添加cookies属性,用于获取所有带来过来的cookies // 设置以后,会在res对象中注入cookie方法,用于设置cookie // app.use(cookieParser(‘1111’)) // 使用111对cookie加密 app.use(cookieParser()); app.use(require(‘./middlewares/tokenHandleware’)) // 设置跨域请求 // app.use(require(‘./middlewares/coresHandleware’))
/*
- 发送请求的时,会根据请求的路径,从指定的目录中查找是否存在该文件,如果存在,则相应文件内容,而不再移交给后续的中间件,
- 如果不存在文件,则直接移交给后续的中间件 */
app.use(express.static(rootPath, { index: ‘index.html’ //默认访问页面,默认值为index.html,可修改 })); // app.use(‘/static’, express.static(rootPath))// 也可以针对访问某个指定api路径,来标识需要 返回静态资源
/*
- 默认res无法解析post请求的参数,也就是请求体
- 使用该中间件后表示,当Content-Type是”application/x-www-form-urlencoded”,使用该中间件处理 / app.use(express.urlencoded({ extended: true })) /**
- 默认res无法解析post请求的参数,也就是请求体
- 使用该中间件后表示,当Content-Type是”application/json”,使用该中间件处理 */ app.use(express.json()) app.use(‘/api/admin’, require(‘./api/admin’)) // 除了api请求 app.use(‘/api/student’, require(‘./api/student’)) app.use(require(‘./middlewares/errMiddleware’)) // 处理所有的错误请求 app.listen(12306, () => { console.log(‘server on 12306 has started’) }) ```
secret: 'lantong'
session用来加密的字符串,浏览器收到会保存在cookie里面- 使用
express-session
中间件以后,在req里面会注入session对象
服务器设置session
使用session中间件以后,req中会自动添加session对象
const express = require('express');
const router = express.Router();
const { getResult } = require('./sendHelper');
const AdminService = require('../../services/adminService');
const crypter = require('../../util/crypt')
router.get('/', (req, res, next) => {
const { loginName, loginPwd } = req.query;
AdminService.getAdminByLoginPwdAndLoginName(loginName, loginPwd).then(resp => {
// res.header("set-cookie", `token=${resp.id};domain=localhost;path=/;max-age=3600;`);
//1. 使用cookie和header做验证信息
// const value = crypter.encrypt(resp.id.toString());
// res.cookie('token', value, {
// path: '/',
// maxAge: 7 * 24 * 3600 * 1000, //此处是毫秒,
// // signed: true 不适用cookie-parser自动加密
// })
// res.header('Authorization', value)
//2. 使用session做验证信息
req.session.loginUser = resp;
res.send(getResult(resp))
}).catch(err => next(err))
})
router.post('/', (req, res, next) => {
AdminService.addAdmin(req.body).then(resp => {
res.send(getResult(resp))
}).catch(err => next(err))
})
module.exports = router;
服务端验证session
const { pathToRegexp } = require('path-to-regexp');
const ceyptor = require('../../util/crypt')
const needTokenApi = [
{ method: 'GET', path: '/api/student' },
{ method: 'PUT', path: '/api/student/:id' }
]
module.exports = function (req, res, next) {
const apis = needTokenApi.filter(api => {
return api.method === req.method && pathToRegexp(api.path).test(req.path);
})
if (apis.length === 0) {
next();
return;
}
//1. 使用cookie和header验证身份
// let token = req.cookies.token || req.headers.Authorization; //未加密
// console.log('req.cookies.token', ceyptor.decrypt(req.cookies.token)) // 解密token
// // let token = req.signedCookies.token || req.headers.Authorization; 不使用,因为自动加密,header无法加密
// if (!token) {
// throw Error('you have not access the api');
// }
//2. 使用session验证身份
console.log(req.session);
if (req.session.loginUser) {
next();
} else {
throw Error('you have not access the api');
}
}
session和cookie的关系
session是默认存在cookie里面的,所以需要设置客户端允许,携带cookie才会有效