(一)
1.电脑安装redis
下载地址
点击下载
提取码 wwhh
2.安装好后,进入到安装目录下启动redis
执行启动:
redis-server.exe redis.windows.conf
(二)Express 项目配置 Redis
- expree项目安装redis依赖
npm install express redis dotenv
2.创建 .env 文件,复制下面的2行到.env文件中
REDIS_HOST=localhost
REDIS_PORT=6379
2.1创建 Redis 客户端,建议在应用入口app.js初始化
app.js文件
// app.js
// ... 其他 require 语句 ...
const redis = require('redis');
const config = require("./config");
var app = express();
var http = require("http");
var server = http.createServer(app);
// ========== Redis 客户端初始化(从这里开始添加) ==========
// 创建 Redis 客户端实例
const redisClient = redis.createClient({
url: process.env.REDIS_URL || 'redis://localhost:6379' // 支持环境变量配置
});
// 处理连接错误
redisClient.on('error', (err) => {
console.error('Redis连接错误:', err);
});
// 异步连接Redis
(async () => {
try {
await redisClient.connect();
console.log('Redis连接成功');
} catch (err) {
console.error('Redis连接失败:', err);
process.exit(1); // 如果Redis连接失败,退出应用
}
})();
// 将redisClient挂载到app实例上,方便后续路由使用
app.locals.redisClient = redisClient;
// ========== Redis 初始化结束 ==========
// 错误处理中间件中添加 Redis 关闭逻辑
process.on('SIGINT', () => {
redisClient.quit().then(() => {
console.log('Redis连接已关闭');
process.exit(0);
});
});
server.listen("5000", () => {
console.log("启动成功");
});
3.实现express登录接口保存token到redis
// 登录接口
var db = require("../utils/db");
// 导入密码加密
const bcrypt = require("bcryptjs");
// 导入jwt 包来生成token
const jwt = require("jsonwebtoken");
// 导入密钥
const config = require("../config");
exports.login = (req, res) => {
// 获取客户端提交到服务器的用户信息
const userinfo = req.body;
// console.log('前端数据', userinfo)
// 定义sql语句,根据用户名查询用户的信息
const sql = `select * from ev_users where username=?`;
// 执行sql语句,根据用户名查询用户的信息
db.query(sql, userinfo.username, async (err, results) => {
// 执行sql语句失败
if (err) return res.cc(err);
// 执行sql语句成功,但是获取到的数据条件不等于1
if (results.length !== 1) return res.cc("登录失败!");
const compareResult = bcrypt.compareSync(
userinfo.password,
results[0].password
);
if (!compareResult) {
return res.cc("登录失败!");
}
// 生成jwt的token字符串
// 清空用户信息的密码和头像
const user = {
...results[0],
password: "",
user_pic: ""
};
console.log("YONGHU", user);
// 对用户的信息进行加密,生成token字符串
const tokenStr = jwt.sign(user, config.jwtSecretKey, {
expiresIn: "10h", // token 有效期为10小时
});
try {
// 获取Redis客户端实例
const redisClient = req.app.locals.redisClient;
// 将Token存储到Redis
await redisClient.setEx(
`token:${user.id}`, // 键名格式: token:用户ID
36000, // 过期时间(秒): 10小时 = 3600秒/小时 × 10
tokenStr // 值: JWT令牌字符串
);
const storedToken = await redisClient.get(`token:${user.id}`);
console.log('[Redis验证] 存储的Token:', storedToken);
console.log('[Redis验证] 剩余TTL:', await redisClient.ttl(`token:${user.id}`));
console.log(`Token已存入Redis (用户ID: ${user.id})`);
// 响应客户端保持不变
res.send({
status: 0,
message: "登录成功!",
token: "Bearer " + tokenStr,
});
} catch (redisError) {
console.error('Redis存储失败:', redisError);
// Redis错误时仍返回登录成功,但记录错误信息
res.send({
status: 0,
message: "登录成功,但Token缓存失败",
token: "Bearer " + tokenStr,
});
}
});
};
- 验证 Redis 存储
前端或者用postman发送登录接口,登录成功后验证redis里面是否存在token
1.前端登录成功
2.验证token 是否在redis
在 Redis 目录下启动 CLI
redis-cli.exe
查询数据
127.0.0.1:6379> KEYS *
此时ID为46的token 保存到了redis中
退出登录后从redis里面删除token
退出登录接口
exports.logout = async (req, res) => {
try {
// 从请求头获取token (格式: Bearer <token>)
const tokenHeader = req.headers.authorization;
if (!tokenHeader || !tokenHeader.startsWith('Bearer ')) {
return res.cc("授权信息无效", 1);
}
// 提取实际token值 (去除"Bearer "前缀)
const token = tokenHeader.split(' ')[1];
// 验证并解码token
let decoded;
try {
decoded = jwt.verify(token, config.jwtSecretKey);
} catch (err) {
// Token无效(过期或签名错误)
return res.cc("授权信息已过期或无效", 1);
}
// 获取Redis客户端
const redisClient = req.app.locals.redisClient;
// 从Redis删除该用户的token
const deleteResult = await redisClient.del(`token:${decoded.id}`);
if (deleteResult === 1) {
console.log(`用户 ${decoded.id} 退出登录成功,Token已删除`);
res.cc("退出登录成功", 0);
} else {
console.log(`用户 ${decoded.id} 退出登录但Token未找到`);
res.cc("退出登录成功", 0); // 即使未找到也返回成功,可能已过期
}
} catch (err) {
console.error("退出登录处理错误:", err);
res.cc("服务器内部错误", 1);
}
};