什么是 session?
session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;
为什么使用 session 替换 cookie?
因为 cookie 比较危险,容易暴露用户的隐私信息;而 session 是存储在 server 端的,所以不存在这个问题。
cookie 只存储 userId,具体的用户信息存储在 session 里。
例子:使用 session 实现登录
const http = require('http');
const querystring = require('querystring');
const PORT = 8000;
// session 存储
const SESSION_DATA = {};
const server = http.createServer(async (req, res) => {
const url = req.url; // /api/user/login?id=1
req.path = url.split('?')[0]; // /api/user/login
req.query = querystring.parse(url.split('?')[1]); // id=1 => { id: 1 }
const method = req.method; // 请求方法
// 解析 cookie
req.cookie = {};
req.headers.cookie && req.headers.cookie.split(';').forEach(item => {
if (!item) {
return
}
const [name, value] = item.trim().split('=');
req.cookie[name] = value;
});
const userId = req.cookie.userId;
if (method === 'GET' && req.path === '/api/user/login') {
const { username, password } = req.query;
if (username === 'bradxu' && password === '123') {
// userId 应该是登录成功后查询数据库返回的值,这里我们生成一个固定值
const userId = "1234";
if (!SESSION_DATA[userId]) {
SESSION_DATA[userId] = {
username
};
} else {
SESSION_DATA[userId].username = username;
}
res.setHeader('Set-Cookie', `userId=${userId}; path=/; httpOnly`);
res.end('Login success');
}
res.end('Login failed');
}
if (method === 'GET' && req.path === '/api/user/login-check') {
if (userId && SESSION_DATA[userId] && SESSION_DATA[userId].username) {
res.end('User logged in');
}
res.end('Not logged in, please log in first');
}
});
server.listen(PORT, () => {
console.log('listening on port 8000!');
});
问题:
上面的例子我们直接使用内存变量来存储 session,这样会有些问题。
- 进程内存有限,如果访问量过大,
SESSION_DATA
变量就会变大,容易造成内存溢出 - 正式上线运行是多线程,进程之间的内存无法共享
所以我们考虑使用 redis 内存数据库来作为 session 的存储。具体使用方法见:npm redis
网友评论