前端安全:别让你的应用变成黑客的游乐场

前端安全:别让你的应用变成黑客的游乐场

毒舌时刻

这代码写得跟网红滤镜似的——仅供参考。

各位前端同行,咱们今天聊聊前端安全。别告诉我你还在写明文存储密码,那感觉就像把家门钥匙挂在门口——方便,但不安全。

为什么你需要前端安全

最近看到一个项目,登录表单直接把密码发送到服务器,没有任何加密。我就想问:你是在做应用还是在给黑客送大礼?

反面教材

// 反面教材:不安全的登录 // 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 防护

// 正确姿势:防止 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 // 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> ); } 

毒舌点评:这才叫现代前端,安全第一,让黑客无处下手。

Read more

前端知识点梳理,前端面试复习

一:从输入 URL 到页面渲染是一个经典的综合性考题 1.URL 的标准组成部分 一个完整的 URL 结构如下: scheme://host:port/path?query#fragment URI 用字符串标识某一互联网资源,而URL 表示资源的地点(互 联网上所处的位置)。可见URL是URI 的子集。 URI 和 URL 的区别? * URI (Uniform Resource Identifier) 是统一资源标识符,是一个大概念。 * URL (Uniform Resource Locator) 是统一资源定位符,它不仅标识资源,还提供了找到资源的方式(比如协议)。可以理解为 URL 是 URI 的子集。 为什么 URL 中有些字符会被转义(

web: jwt令牌构成、创建的基本流程及原理

一、JWT 的构成 1. 概念 json web token(JWT) 本质是一串含义验证信息的字符串,服务器根据JWT和密钥,经过加密算法,验证该字符串是否有效。 2. 构成 JWT由Header、Payload、Signature构成,每个部分都是一个token,如下: 它们的实际含义如下:         Header:json字符串,指定加密算法(供Signature使用)和类型(一般写死为“JWT”)         Payload:json字符串,包含通用信息(如发布者iss、发布时间戳iat、过期时间戳exp)和自定义属性(如uid)         Signature:加密函数,输入“Header”、“Payload”、“密钥”,输出密文 3. 验证方式 STEP 1:客户端登录,传递用户名、密码,

DeepSeek-R1-Distill-Qwen-1.5B与Llama3轻量版对比:推理速度与精度评测

DeepSeek-R1-Distill-Qwen-1.5B与Llama3轻量版对比:推理速度与精度评测 1. 评测背景与目标 最近在部署轻量级大模型时,我遇到了一个实际的选择难题:DeepSeek-R1-Distill-Qwen-1.5B和Llama3轻量版,到底哪个更适合我的边缘计算场景?这两个模型都在1.5B参数级别,都号称在保持精度的同时大幅提升推理速度,但实际表现如何呢? 我决定做一个全面的对比评测,不是简单的跑分,而是从实际部署、使用体验、性能表现等多个维度来评估。毕竟,模型好不好用,光看论文指标是不够的,得在实际环境中跑一跑才知道。 这次评测的目标很明确:帮大家搞清楚这两个模型各自的优势在哪里,适合什么场景,以及在实际部署中需要注意什么。我会用最直白的方式,把测试过程、结果和分析都展示出来,让你看完就能做出选择。 2. 模型介绍与特点分析 2.1 DeepSeek-R1-Distill-Qwen-1.5B:专为推理优化的轻量选手 DeepSeek-R1-Distill-Qwen-1.5B这个模型,名字听起来有点长,但理解起来其实很简单。它是DeepSeek