跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.js大前端

前端安全实践:密码加密与 XSS CSRF 防护

探讨了前端安全的重要性及常见漏洞的防护措施。主要内容包括密码明文传输的风险及使用 bcrypt 进行加密的方案、XSS 攻击的 DOMPurify 净化与 CSP 策略配置、以及 CSRF 攻击的 Token 验证机制。通过对比不安全代码与正确实现,帮助开发者构建更安全的 Web 应用。

极客零度发布于 2026/4/6更新于 2026/9/468 浏览

前端安全

为什么你需要前端安全

最近看到一个项目,登录表单直接把密码发送到服务器,没有任何加密。这存在严重的安全隐患。

反面教材
// 反面教材:不安全的登录
// components/LoginForm.jsx
export default function LoginForm() {
  const [username, setUsername] = useState('');
  const [password, setPassword] = useState('');
  const handleSubmit = async (e) => {
    e.preventDefault();
    // 直接发送明文密码
    const response = await fetch('/api/login', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ username, password }) // 明文密码
    });
    if (response.ok) {
      // 登录成功
    }
  };
  return (
    <form onSubmit={handleSubmit}>
      <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="用户名" />
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="密码" />
      <button type="submit">登录</button>
    </form>
  );
}

*注意:密码在网络传输中是明文,本地存储也是明文,极易被截获。

前端安全的正确姿势

1. 密码加密

使用哈希算法对密码进行加密存储,而非明文。

// 正确姿势:密码加密
// utils/auth.js
import bcrypt from 'bcryptjs';

export async function hashPassword(password) {
  const salt = await bcrypt.genSalt(10);
  return await bcrypt.hash(password, salt);
}

export async function comparePassword(password, hashedPassword) {
  return await bcrypt.compare(password, hashedPassword);
}

// 服务端登录处理
// api/login.js
export default async function handler(req, res) {
  const { username, password } = req.body;
  const user = await User.findOne({ username });
  if (!user) {
    return res.status(401).json({ error: '用户不存在' });
  }
  const isMatch = await comparePassword(password, user.password);
  if (!isMatch) {
    return res.status(401).json({ error: '密码错误' });
  }
  // 生成 JWT token
  const token = generateToken(user.id);
  res.json({ token });
}
2. XSS 防护

使用库净化输入内容并设置内容安全策略(CSP)。

// 正确姿势:防止 XSS
// components/Comment.jsx
import DOMPurify from 'dompurify';

export default function Comment({ content }) {
  // 净化 HTML 内容
  const sanitizedContent = DOMPurify.sanitize(content);
  return (
    <div dangerouslySetInnerHTML={{ __html: sanitizedContent }} />
  );
}
// 服务器端设置 CSP 头
// next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          {
            key: 'Content-Security-Policy',
            value: "default-src 'self'; script-src 'self' 'unsafe-inline' https://trusted-cdn.com"
          }
        ]
      }
    ];
  }
};
3. CSRF 防护

在请求中携带并验证 CSRF Token。

// 正确姿势:防止 CSRF
// pages/api/protected.js
import csrf from 'csurf';
const csrfProtection = csrf({ cookie: true });

export default function handler(req, res) {
  csrfProtection(req, res, () => {
    // 受保护的 API 逻辑
  });
}
// 客户端
// components/Form.jsx
export default function Form() {
  const [csrfToken, setCsrfToken] = useState('');
  useEffect(() => {
    // 获取 CSRF token
    fetch('/api/csrf-token')
      .then(res => res.json())
      .then(data => setCsrfToken(data.token));
  }, []);

  const handleSubmit = async (e) => {
    e.preventDefault();
    await fetch('/api/protected', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': csrfToken
      },
      body: JSON.stringify({ data: 'test' })
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="hidden" name="_csrf" value={csrfToken} />
      {/* 表单内容 */}
    </form>
  );
}

目录

  1. 前端安全
  2. 为什么你需要前端安全
  3. 反面教材
  4. 前端安全的正确姿势
  5. 1. 密码加密
  6. 2. XSS 防护
  7. 3. CSRF 防护

更多推荐文章

查看全部
  • VS Code 中 GitHub 扩展登录报错:尚未完成授权此扩展使用 GitHub 的操作
  • 前端安全实战:密码加密与常见攻击防护
  • C++ STL set 与 map 底层封装原理详解
  • AI 产品经理转型指南:角色职责与学习路径
  • Linux Crontab 定时任务配置、用法与实战案例
  • 2025 年 12 月 GESP C++ 一级真题解析
  • GitHub 上值得参考的量化交易开源项目
  • 开源大模型深度评测:四大模型场景化对比与选型指南
  • SpringBoot 项目从零搭建指南
  • 前端实战:拦截右键菜单并实现自定义弹窗逻辑
  • 基于 Web-Check 与内网穿透的远程网站安全检测方案
  • 基于 n8n 与 MaaS 平台的智能写作工作流构建指南
  • 直流无刷电机 FOC 控制算法详解与 STM32 实现
  • 北漂转行软件测试:从零开始的外企高薪实战指南
  • Windows 下 VSCode 连接 VMware 虚拟机搭建 C++ 开发环境(Ubuntu 为例)
  • 堆排序算法详解与实现
  • ClawdBot 本地部署实战:vLLM 后端与设备授权全链路解析
  • C/C++编译成共享库(.so)完整流程与动态链接解析
  • Golang Gin 框架中的表单处理与数据绑定
  • Spring Cloud Alibaba 微服务 SkyWalking 全链路追踪实战

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online