?cookie会在浏览器关闭的时候, 销毁
const express = require("express");
//1. 安装 cookie-parser npm i cookie-parser
//2. 引入 cookieParser 包
const cookieParser = require("cookie-parser");
const app = express();
//3. 设置 cookieParser 中间件
app.use(cookieParser());
//4-1 设置 cookie
app.get("/set-cookie", (request, response) => {
// 不带时效性
response.cookie("username", "wangwu"); // 会在浏览器关闭的时候, 销毁
// 带时效性
response.cookie("email", "123456789@qq.com", { maxAge: 5 * 60 * 1000 }); //单位毫秒
//响应
response.send("Cookie的设置");
});
//4-2 读取 cookie
app.get("/get-cookie", (request, response) => {
//读取 cookie
console.log(request.cookies);
//响应体
response.send("Cookie的读取");
});
//4-3 删除cookie
app.get("/delete-cookie", (request, response) => {
//删除
response.clearCookie("username");
//响应
response.send("cookie 的清除");
});
//4. 启动服务
app.listen(3000, () => {
console.log("服务已经启动....");
});
不同浏览器中的 cookie 是相互独立的,不共享
const express = require("express");
//1. 安装包 npm i express-session connect-mongo
//2. 引入 express-session connect-mongo
const session = require("express-session");
const MongoStore = require("connect-mongo");
const app = express();
//3. 设置 session 的中间件
app.use(
session({
name: "sid", //设置cookie的name,默认值是:connect.sid
secret: "atguigu", //参与加密的字符串(又称签名)密钥,加密钥匙
saveUninitialized: false, //是否为每次请求都设置一个cookie用来存储session的id
resave: true, //是否在每次请求时重新保存session
store: MongoStore.create({
mongoUrl: "mongodb://127.0.0.1:27017/project", //数据库的连接配置,把sesion信息存在对应的数据库里面
}),
cookie: {
httpOnly: true, // 开启后,前端无法通过 JS 操作拿到这个存放在cookie的session值
maxAge: 1000 * 300, // 这一条 是控制 sessionID 的过期时间的!!!
},
})
);
//创建 session
app.get("/login", (req, res) => {
//设置session
req.session.username = "zhangsan";
req.session.email = "zhangsan@qq.com";
res.send("登录成功");
});
//获取 session
app.get("/home", (req, res) => {
console.log("session的信息");
console.log(req.session.username);
if (req.session.username) {
res.send(`你好 ${req.session.username}`);
} else {
res.send("登录 注册");
}
});
//销毁 session
app.get("/logout", (req, res) => {
//销毁session
// res.send('设置session');
req.session.destroy(() => {
res.send("成功退出");
});
});
//监听端口, 启动服务
app.listen(3000, () => {
console.log("服务已经启动, 端口 3000 正在监听中....");
});
cookie 和 session 的区别主要有如下几点:1. 存在的位置? ?cookie :浏览器端? ?session :服务端2. 安全性? ?cookie 是以明文的方式存放在客户端的,安全性相对较低? ?session 存放于服务器中,所以安全性 相对 较好3. 网络传输量? ?cookie 设置内容过多会增大报文体积, 会影响传输效率? ?session 数据存储在服务器,只是通过 cookie 传递 id ,所以不影响传输效率4. 存储限制? ? 浏览器限制单个 cookie 保存的数据不能超过 4K ,且单个域名下的存储数量也有限制? ? session 数据存储在服务器中,所以没有这些限制
//导入 jsonwebtokan --> npm i jsonwebtoken --save
const jwt = require('jsonwebtoken');
//创建 token
// jwt.sign(数据, 加密字符串, 配置对象)
let token = jwt.sign({
username: 'zhangsan'
}, 'test', {
expiresIn: 60 //单位是 秒
})
//解析 token
jwt.verify(token, 'test', (err, data) => {
if(err){
console.log('校验失败~~');
return
}
console.log(data);
})
扩展阅读: https://www.ruanyifeng.com/blog/2018/07/json_web_token-tutorial.html
下面express例子,是在登录接口模块展示:
(1)在项目中的models(存放文档类型,类似ts模块)文件夹下 新建文档UserModel.js,定义登录接口的数据类型:
文档?UserModel.js代码如下:
//导入 mongoose
const mongoose = require('mongoose');
//创建文档的结构对象
//设置集合中文档的属性以及属性值的类型
let UserSchema = new mongoose.Schema({
//标题
username: String,
password: String
});
//创建模型对象 对文档操作的封装对象 数据库的表名为users
let UserModel = mongoose.model('users', UserSchema);
//暴露模型对象
module.exports = UserModel;
(2)在登录接口模块,核对账号信息,生成token,返回数据
接口文档?UserModel.js代码如下:
var express = require("express");
var router = express.Router();
//导入 jwt --> npm i jsonwebtoken --save
const jwt = require("jsonwebtoken");
//导入配置文件
const { secret } = require("../../config/config"); //获取加密字段,自定义字符串
//导入 用户的模型
const UserModel = require("../../models/UserModel");
// 导入md5加密--》 npm install md5 --save
const md5 = require("md5");
//登录操作
router.post("/login", (req, res) => {
//获取用户名和密码
let { username, password } = req.body;
//查询数据库
UserModel.findOne({ username: username, password: md5(password) })
.then((data) => {
//判断 data
if (!data) {
return res.json({
code: "2002",
msg: "用户名或密码错误~~~",
data: null,
});
}
//创建当前用户的 token
let token = jwt.sign(
{
username: data.username,
_id: data._id,
},
secret,
{
expiresIn: 60 * 60 * 24 * 7,
}
);
/*
这里有需要的,可以把tolen存储进对应数据库
*/
//响应 token
res.json({
code: "0000",
msg: "登录成功",
data: token,
});
})
.catch((err) => {
//判断
if (err) {
res.json({
code: "2001",
msg: "数据库读取失败~~~",
data: null,
});
return;
}
});
});
//退出登录
router.post("/logout", (req, res) => {
//销毁 tolen 删除数据库该token值
res.render("success", { msg: "退出成功", url: "/login" });
});
module.exports = router;
在项目中 新建文件夹??middlewares (存放所有中间件)
在文件夹下新建文档?checkTokenMiddleware.js 封装好读取token的中间件
文档?checkTokenMiddleware.js代码如下:
// token 中间件
//导入 jwt --> npm i jsonwebtoken --save
const jwt = require("jsonwebtoken");
//读取配置项
const { secret } = require("../config/config"); //获取加密字段,自定义字符串
//声明中间件
module.exports = (req, res, next) => {
//获取 token
let token = req.get("token");
//判断
if (!token) {
return res.json({
code: "2003",
msg: "token 缺失",
data: null,
});
}
//校验 token secret是自定义字符串
jwt.verify(token, secret, (err, data) => {
//检测 token 是否正确
if (err) {
return res.json({
code: "2004",
msg: "token 校验失败~~",
data: null,
});
}
//保存用户的信息
req.user = data; // req.session req.body
//如果 token 校验成功
next();
});
};
在需要token校验的路由模块,引入中间件 进行校验,通过才会走下面的接口数据逻辑