怎么实现登录不用数据库也能搞定,代码简单又实用分享
- 问答
- 2025-12-31 07:19:29
- 6
(引用来源:基于服务器端Session、客户端Token及文件存储的常见轻量级认证方案整合)
想做个简单的登录功能,但又嫌装数据库太麻烦?比如就是个个人小工具、毕业设计演示,或者一个用户量极小的内部应用,确实没必要上MySQL、Redis这些大家伙,不用数据库,登录功能照样能玩得转,而且代码可以非常简洁,下面就来分享几种简单实用的办法,咱们用最直白的思路和代码来说明。
第一种办法:用文件当数据库,配合服务器Session
这是最直接能想到的替代方案,既然数据库的本质就是存东西,那一个文本文件或者JSON文件也能存用户信息啊。
思路是这样的:
- 用户注册时,我们把用户名和密码(切记要加密!)写到一个文件里,比如叫
users.json。 - 用户登录时,我们读取这个文件,核对输入的用户名和密码是否匹配。
- 如果匹配成功,就在服务器端创建一个Session,标记这个用户已经登录了。
这里的关键是Session,你可以把它理解成服务器给每个登录成功的用户发的一个“临时通行证”,服务器会把这个通行证编号(Session ID)通过Cookie告诉用户的浏览器,浏览器下次请求时带着这个编号,服务器就知道是谁了,用户信息存在服务器内存里,文件里只存永久的账号密码。
我们用Node.js和Express框架写个极简例子,一看就懂:

// 引入必要的模块
const express = require('express');
const session = require('express-session');
const fs = require('fs');
const app = express();
// 启用Session中间件(秘密密钥自己设一个)
app.use(session({
secret: '你的秘密字符串',
resave: false,
saveUninitialized: false
}));
// 用于解析POST请求中的JSON数据
app.use(express.json());
// 注册接口
app.post('/register', (req, res) => {
const { username, password } = req.body;
// 1. 读取现有的用户文件(如果存在的话)
let users = [];
try {
users = JSON.parse(fs.readFileSync('users.json'));
} catch (error) {
// 文件不存在也没关系,就当是空数组
}
// 2. 检查用户名是否已存在
if (users.find(user => user.username === username)) {
return res.status(400).send('用户名已存在');
}
// 3. 密码加密(这里用简单的哈希,实际项目要用bcrypt等强加密库)
// 为了演示,我们假设有一个简单的哈希函数
const hashedPassword = simpleHash(password);
// 4. 保存新用户
users.push({ username, password: hashedPassword });
fs.writeFileSync('users.json', JSON.stringify(users, null, 2));
res.send('注册成功!');
});
// 登录接口
app.post('/login', (req, res) => {
const { username, password } = req.body;
// 1. 读取用户文件
let users = [];
try {
users = JSON.parse(fs.readFileSync('users.json'));
} catch (error) {
return res.status(500).send('系统错误');
}
// 2. 查找用户并验证密码
const user = users.find(u => u.username === username);
if (user && user.password === simpleHash(password)) {
// 3. 登录成功!把用户信息存到Session里
req.session.userId = username; // 通常存用户ID,这里用用户名简化
req.session.isLogin = true;
return res.send('登录成功!');
} else {
res.status(401).send('用户名或密码错误');
}
});
// 一个需要登录才能访问的页面
app.get('/profile', (req, res) => {
if (req.session.isLogin) {
res.send(`欢迎你,${req.session.userId}!`);
} else {
res.status(401).send('请先登录!');
}
});
// 注销接口
app.post('/logout', (req, res) => {
req.session.destroy();
res.send('已退出登录');
});
// 一个简单的哈希函数示例(仅用于演示,不适用于生产环境)
function simpleHash(str) {
// 生产环境请务必使用专业的密码哈希库,如 bcrypt
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) - hash) + str.charCodeAt(i);
hash |= 0; // 转换为32位整数
}
return hash.toString();
}
app.listen(3000, () => console.log('服务器在3000端口启动'));
这个例子的好处是逻辑清晰,Session由服务器管理,相对安全,缺点是如果服务器重启,内存里的Session就丢了,用户需要重新登录,对于小应用来说,这通常可以接受。
第二种办法:用Token,信息全放在客户端
这种方法更“无状态”,服务器完全不记录谁登录了,它的核心是Token(令牌)。
思路是这样的:

- 登录时,服务器核对用户名和密码(还是从文件读)。
- 核对成功,服务器生成一个Token,这个Token里其实就编码了用户信息(比如用户名),并且附带了数字签名,防止被篡改。
- 把这个Token发回给客户端(比如浏览器的LocalStorage里)。
- 客户端以后每次请求API,都在请求头里带上这个Token。
- 服务器收到Token,验证一下签名是否有效,如果有效就认为用户已登录,并从Token里解析出用户信息。
这种方法连服务器重启都不怕,因为登录状态全在客户端手里拿着,常用的Token标准是JWT(JSON Web Token)。
我们还是用Node.js写个概念性的例子,忽略掉JWT复杂的签名细节,用简化的思路表达:
const express = require('express');
const fs = require('fs');
const app = express();
app.use(express.json());
// 假设的Token生成与验证函数(真实项目请使用jsonwebtoken等成熟库)
function generateToken(username) {
// 简单模拟:把用户名和一个过期时间拼起来,然后做个假签名
const payload = { username, exp: Date.now() + (60 * 60 * 1000) }; // 过期时间1小时后
const fakeSignature = 'signed_' + Buffer.from(JSON.stringify(payload)).toString('base64');
return fakeSignature;
}
function verifyToken(token) {
try {
// 模拟验证签名和解码
const decodedStr = Buffer.from(token.replace('signed_', ''), 'base64').toString();
const payload = JSON.parse(decodedStr);
// 检查过期时间
if (payload.exp < Date.now()) {
return null; // Token过期
}
return payload; // 返回Token里的信息
} catch (e) {
return null; // Token无效
}
}
// 登录接口(注册接口和第一种方法类似,省略)
app.post('/login', (req, res) => {
const { username, password } = req.body;
// ... 从文件读取用户并验证密码的代码同上 ...
if (/* 验证成功 */) {
// 生成Token并返回给客户端
const token = generateToken(username);
res.json({ success: true, token: token });
} else {
res.status(401).json({ success: false, message: '登录失败' });
}
});
// 需要认证的接口
app.get('/api/data', (req, res) => {
// 客户端需要在请求头里带上 Authorization: Bearer <token>
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // 获取Bearer后面的Token
if (!token) {
return res.status(401).send('缺少Token');
}
const userData = verifyToken(token);
if (userData) {
// Token有效,userData里就有用户名等信息
res.json({ message: `这是${userData.username}的私有数据` });
} else {
res.status(403).send('无效或过期的Token');
}
});
app.listen(3000);
这种方法的优点是服务器轻松,扩展性好,缺点是Token一旦发出,在过期前服务器无法主动让它失效(除非引入额外的黑名单机制,但那又需要存储了)。
对于“不用数据库”的登录,核心就是找替代品来存用户凭证(文件)和管理登录状态(Session或Token)。
- 文件+Session:简单直观,适合传统的网页应用,服务器有状态。
- 文件+Token:更现代,适合前后端分离的API接口,服务器无状态。
选择哪种,看你的具体需求,无论哪种,都要牢记:密码绝不能明文存储,一定要用可靠的哈希算法(示例中的simpleHash仅为演示,实际请用bcrypt或argon2)进行加密,这样,即使文件被泄露,攻击者也很难反推出原始密码,这些方法在用户量小、安全性要求不是极端高的场景下,是完全可行且非常实用的。
本文由歧云亭于2025-12-31发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/71749.html
