网站的用户登录一般怎么做的新手入门

不会代码也能搞定?3个免费工具拆解网站用户登录逻辑

很多新手看着别人的网站都有“登录”按钮,心里直打鼓:自己不会代码,想做网站是不是就没戏了?其实真没那么难。现在市面上有大量的免费工具,能把最复杂的逻辑封装好,让你像搭积木一样把登录功能拼出来。

咱们今天不聊那些高大上的架构,就聊聊最朴素的网站的用户登录一般怎么做的。我会把过程拆解成你能直接照做的步骤,哪怕你连服务器都没买过,也能看懂这一套流程是怎么跑通的。特别是对于在浙江这种互联网氛围浓厚、但技术门槛看似很高的地区的朋友,这种“低代码”甚至“无代码”的思路,能帮你省下好几千的外包费。

一、 先别急着写代码,搞清楚登录到底在干嘛

在动手之前,你得明白“登录”这两个字背后,服务器和浏览器之间到底在传递什么。很多新手一上来就纠结用PHP还是Python,结果发现根本跑不通。

1. 登录的本质是“身份验证”

想象一下你去公司上班,要刷工牌。

  • 工牌就是你的密码。
  • 门禁机就是你的服务器。
  • 刷进去的动作就是发送请求。

网站登录也是这样。你在前端输入用户名和密码,点击按钮。这时候,浏览器会把这些信息打包,发给后端服务器。后端拿到信息后,去数据库里查:“这个人存在吗?密码对吗?” 如果都对,后端会发一张“电子工牌”给浏览器,这张工牌通常叫 Token 或者 Session ID。 接下来你再访问需要权限的页面,浏览器就会自动带上这张“电子工牌”,服务器一看:“哦,是刚才验证过的人,放行。”

2. 为什么不能只存密码?

这是新手最容易踩的坑。很多教程让你直接把密码存进数据库,比如 password: 123456。 千万别这么干! 一旦数据库泄露,黑客拿着明文密码就能去撞库你的邮箱、支付宝、微信。 正确的做法是哈希加密。 比如你的密码是 abc123,存入数据库的不是 abc123,而是一串乱码,比如 5f4dcc3b5aa765d61d8327deb882cf99。 当你下次输入 abc123 时,服务器再次计算哈希值,如果和数据库里的一模一样,就认为密码正确。 注意,哈希是不可逆的。黑客即使偷走了数据库,看到那串乱码,也算不出原始密码是什么(除非他穷举所有可能的密码组合,这叫暴力破解,但难度极大)。

二、 环境准备:用免费工具把架子搭起来

既然目标是“不会代码也能做”,那我们就选最省心的方案。这里我推荐三个在开发者圈子里口碑很好的免费工具组合:

  1. 后端框架:Node.js + Express
    • 理由:JavaScript 语言,前后端通用,语法简单,不像 Java 那么啰嗦。
    • 免费:开源,下载即用。
  2. 数据库:SQLite
    • 理由:它不是一个独立的数据库服务,而是一个文件。你不需要配置复杂的 MySQL 账号密码,不需要启动服务。创建一个 .db 文件就是你的数据库。
    • 免费:内置在 Node.js 生态中,零成本。
  3. 开发环境:VS Code + Live Server
    • 理由:VS Code 是微软出的免费编辑器,插件丰富。Live Server 插件可以一键在浏览器预览,自动刷新。
    • 免费:VS Code 永久免费,插件也免费。

浙江视角的小建议: 如果你在浙江,尤其是杭州或宁波,很多中小企业喜欢用轻量级方案。SQLite 非常适合这种场景。如果你的网站初期流量不大(比如日活几百人),SQLite 的性能完全够用,而且维护成本几乎为零。等你流量起来了,再迁移到 MySQL 也不迟,数据格式是通用的。

准备工作步骤:

  1. 去 nodejs.org 下载 LTS 版本(长期支持版),安装。
  2. 安装 VS Code,安装 Live Server 插件。
  3. 新建一个文件夹,比如叫 my-login-site,打开 VS Code。
  4. 在终端里输入 npm init -y 初始化项目。
  5. 安装依赖:npm install express sqlite3 bcryptjs jsonwebtoken
    • express: Web 框架
    • sqlite3: 数据库驱动
    • bcryptjs: 密码加密库(纯 JS 实现,无需编译,适合新手)
    • jsonwebtoken: 生成和验证 Token 的库

三、 核心步骤:从零搭建登录系统

现在,我们开始写代码。别怕,我会把每一步都解释清楚。

第一步:创建数据库表

我们需要一张表来存用户信息。创建 db.js 文件:

const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('users.db');// 创建用户表,如果不存在
db.run(`CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT,username TEXT UNIQUE NOT NULL,password TEXT NOT NULL,created_at DATETIME DEFAULT CURRENT_TIMESTAMP)
`);module.exports = db;

这段代码做了什么?

  • 连接了一个叫 users.db 的文件。
  • 创建了一张 users 表。
  • 字段包括:ID(自增)、用户名(唯一)、密码(存加密后的值)、注册时间。

第二步:实现注册接口

用户得先有账号才能登录。创建 server.js 文件:

const express = require('express');
const bcrypt = require('bcryptjs');
const db = require('./db');
const app = express();
const port = 3000;// 解析 JSON 请求体
app.use(express.json());// 注册接口
app.post('/register', async (req, res) => {const { username, password } = req.body;// 1. 检查用户是否已存在db.get('SELECT * FROM users WHERE username = ?', [username], (err, row) => {if (err) {return res.status(500).json({ error: 'Database error' });}if (row) {return res.status(400).json({ error: 'Username already exists' });}// 2. 加密密码const saltRounds = 10;bcrypt.hash(password, saltRounds, (err, hashedPassword) => {if (err) {return res.status(500).json({ error: 'Hashing error' });}// 3. 插入数据库const stmt = db.prepare('INSERT INTO users (username, password) VALUES (?, ?)');stmt.run(username, hashedPassword, (err) => {if (err) {return res.status(500).json({ error: 'Insert error' });}res.status(201).json({ message: 'User registered successfully' });});});});
});app.listen(port, () => {console.log(`Server running on http://localhost:${port}`);
});

关键点解析:

  • app.use(express.json()):告诉服务器,我要处理 JSON 格式的数据。
  • bcrypt.hash(password, saltRounds, ...):这是核心。saltRounds 是加密强度,10 是推荐值,越高越慢但越安全。
  • 注意:这里我们只做了注册,还没做登录。

第三步:实现登录接口

在 server.js 中继续添加登录逻辑:

const jwt = require('jsonwebtoken');
const SECRET_KEY = 'your-secret-key-change-this-in-production'; // 生产环境务必更换// 登录接口
app.post('/login', async (req, res) => {const { username, password } = req.body;// 1. 查找用户db.get('SELECT * FROM users WHERE username = ?', [username], (err, user) => {if (err) {return res.status(500).json({ error: 'Database error' });}if (!user) {return res.status(400).json({ error: 'Invalid username or password' });}// 2. 验证密码bcrypt.compare(password, user.password, (err, isMatch) => {if (err) {return res.status(500).json({ error: 'Compare error' });}if (!isMatch) {return res.status(400).json({ error: 'Invalid username or password' });}// 3. 生成 Tokenconst token = jwt.sign({ userId: user.id, username: user.username }, SECRET_KEY, {expiresIn: '1h' // Token 有效期 1 小时});res.json({ token });});});
});

关键点解析:

  • bcrypt.compare:把你输入的明文密码和数据库里的哈希值比对。
  • jwt.sign:生成一个 Token。这个 Token 包含了用户 ID 和用户名,并且有签名,防止被篡改。
  • expiresIn: '1h':Token 一小时后失效,过期后用户需要重新登录。

第四步:前端简单演示

虽然我们是讲后端,但前端怎么发请求?创建一个 public/index.html,并在 server.js 开头加上 app.use(express.static('public'));。

<!DOCTYPE html>
<html lang="zh">
<head><meta charset="UTF-8"><title>登录演示</title>
</head>
<body><h2>用户登录</h2><input type="text" id="username" placeholder="用户名"><input type="password" id="password" placeholder="密码"><button onclick="login()">登录</button><button onclick="register()">注册</button><p id="msg"></p><script>async function register() {const username = document.getElementById('username').value;const password = document.getElementById('password').value;const res = await fetch('/register', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ username, password })});const data = await res.json();document.getElementById('msg').innerText = data.message || data.error;}async function login() {const username = document.getElementById('username').value;const password = document.getElementById('password').value;const res = await fetch('/login', {method: 'POST',headers: { 'Content-Type': 'application/json' },body: JSON.stringify({ username, password })});const data = await res.json();if (data.token) {localStorage.setItem('token', data.token);document.getElementById('msg').innerText = '登录成功!Token 已保存';} else {document.getElementById('msg').innerText = data.error;}}</script>
</body>
</html>

四、 代码与配置示例:安全加固

上面的代码能跑,但在生产环境还不够安全。我们需要做两件事:HTTPS 和 速率限制。

1. 使用 Cloudflare 实现免费 HTTPS

很多新手以为 HTTPS 证书要买,其实 Cloudflare 提供了免费的 Universal SSL。

  • 去 Cloudflare 注册账号,把域名解析指向 Cloudflare。
  • 在 Cloudflare 控制台,开启 "Always Use HTTPS"。
  • 这样,所有访问你网站的请求,都会自动强制跳转到 HTTPS。
  • 为什么重要? 登录时传输的密码和 Token,如果走 HTTP(明文),黑客可以拦截。HTTPS 加密后,传输过程是安全的。
  • 根据 Cloudflare 文档 的建议,你应该在源服务器(你的 Node.js 服务)上也配置好信任 Cloudflare 的代理头,防止伪造请求。

2. 防止暴力破解

如果黑客用脚本每秒试 100 次密码,你的服务器会被拖垮。我们需要限制每个 IP 的请求频率。 安装 express-rate-limit: npm install express-rate-limit

在 server.js 中添加:

const rateLimit = require('express-rate-limit');// 限制每个 IP 每 15 分钟最多 10 次登录尝试
const loginLimiter = rateLimit({windowMs: 15 * 60 * 1000, // 15 分钟max: 10, // 最多 10 次message: 'Too many login attempts, please try again later.'
});// 应用到登录接口
app.post('/login', loginLimiter, async (req, res) => {// ... 上面的登录逻辑
});

五、 常见报错与排查

新手最容易遇到这几个问题:

  1. Error: Cannot find module 'express'

    • 原因:你没安装依赖。
    • 解决:在终端运行 npm install express sqlite3 bcryptjs jsonwebtoken express-rate-limit。
  2. 500 Internal Server Error

    • 原因:通常是数据库操作出错,或者代码逻辑抛异常。
    • 解决:看终端里的详细错误日志。如果是 sqlite3 报错,检查文件名是否正确,或者是否被其他进程占用。
  3. 404 Not Found

    • 原因:路由路径写错了,或者前端请求的路径不对。
    • 解决:检查 app.post('/login', ...) 和前端 fetch('/login', ...) 是否一致。
  4. Token 过期,但前端没提示

    • 原因:前端没有处理 401 状态码。
    • 解决:在 fetch 的 then 里,检查 res.status,如果是 401,就清空 localStorage 并跳转回登录页。

六、 小结与互动

看到这里,你应该明白了,网站的用户登录一般怎么做的 其实就这几步:

  1. 前端收集用户名密码。
  2. 后端接收,查数据库。
  3. 密码哈希比对。
  4. 生成 Token 返回。
  5. 前端存储 Token,后续请求携带。

我们用了 Node.js、SQLite、Express、Bcrypt、JWT 这些免费工具,搭建了一个相对安全、轻量级的登录系统。对于个人项目或小型企业官网,这套方案足够用了。

最后,我想问你一个问题: 你的网站目前用的什么技术栈?是 PHP 老古董,还是 Node.js 新贵?或者你正在用 WordPress 这种 CMS? 在评论区聊聊,看看大家是怎么处理用户登录的。有没有人遇到过 Token 刷新导致的 Bug?欢迎交流,咱们一起避坑。