前端安全别让你的网站变成黑客的游乐场毒舌时刻这代码写得跟筛子似的到处都是漏洞。各位前端同行咱们今天聊聊前端安全。别告诉我你还在忽略安全问题那感觉就像在没有锁的房子里放贵重物品——能放但随时可能被偷。为什么你需要关注前端安全最近看到一个项目直接在前端存储用户密码没有任何加密措施。我就想问你是在做网站还是在做慈善反面教材// 反面教材不安全的代码 function Login() { const [username, setUsername] React.useState(); const [password, setPassword] React.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 }) }); const data await response.json(); // 直接存储 token 在 localStorage localStorage.setItem(token, data.token); }; return ( form onSubmit{handleSubmit} input typetext placeholder用户名 value{username} onChange{(e) setUsername(e.target.value)} / input typepassword placeholder密码 value{password} onChange{(e) setPassword(e.target.value)} / button typesubmit登录/button /form ); } export default Login;毒舌点评这代码就像在大街上裸奔一点隐私都没有。正确姿势1. 密码安全// 正确姿势密码安全 // 1. 使用 HTTPS // 2. 密码加密传输 function Login() { const [username, setUsername] React.useState(); const [password, setPassword] React.useState(); const handleSubmit async (e) { e.preventDefault(); // 使用 HTTPS 传输 const response await fetch(/api/login, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ username, password }) }); const data await response.json(); // 使用 httpOnly cookie 存储 token // 服务端设置: res.cookie(token, token, { httpOnly: true, secure: true }); }; return ( form onSubmit{handleSubmit} input typetext placeholder用户名 value{username} onChange{(e) setUsername(e.target.value)} / input typepassword placeholder密码 value{password} onChange{(e) setPassword(e.target.value)} / button typesubmit登录/button /form ); } export default Login;2. XSS 防护// 正确姿势XSS 防护 // 1. 使用 dangerouslySetInnerHTML 时要小心 // 2. 对用户输入进行转义 function CommentList({ comments }) { return ( div {comments.map(comment ( div key{comment.id} {/* 安全的方式直接渲染文本 */} p{comment.content}/p {/* 不安全的方式 */} {/* p dangerouslySetInnerHTML{{ __html: comment.content }} / */} /div ))} /div ); } // 后端转义 // server.js app.post(/api/comments, (req, res) { const { content } req.body; // 转义用户输入 const escapedContent escapeHtml(content); // 存储转义后的内容 db.insert({ content: escapedContent }); res.json({ success: true }); }); function escapeHtml(text) { return text .replace(//g, amp;) .replace(//g, lt;) .replace(//g, gt;) .replace(//g, quot;) .replace(//g, #039;); }3. CSRF 防护// 正确姿势CSRF 防护 // 1. 使用 CSRF token // 2. 验证 Origin/Referer 头 function Form() { const [csrfToken, setCsrfToken] React.useState(); React.useEffect(() { // 从服务端获取 CSRF token async function getCsrfToken() { const response await fetch(/api/csrf-token); const data await response.json(); setCsrfToken(data.token); } getCsrfToken(); }, []); const handleSubmit async (e) { e.preventDefault(); const response await fetch(/api/submit, { method: POST, headers: { Content-Type: application/json, X-CSRF-Token: csrfToken }, body: JSON.stringify({ /* 表单数据 */ }) }); const data await response.json(); console.log(data); }; return ( form onSubmit{handleSubmit} input typehidden name_csrf value{csrfToken} / {/* 表单字段 */} button typesubmit提交/button /form ); } // 服务端验证 // server.js app.post(/api/submit, (req, res) { const csrfToken req.headers[x-csrf-token] || req.body._csrf; if (!csrfToken || !validateCsrfToken(csrfToken)) { return res.status(403).json({ error: CSRF token invalid }); } // 处理请求 res.json({ success: true }); });4. 依赖安全// 正确姿势依赖安全 // 1. 定期更新依赖 // 2. 使用 npm audit 检查漏洞 // 3. 使用 Snyk 等工具监控 // package.json { name: my-app, version: 1.0.0, dependencies: { react: ^18.2.0, react-dom: ^18.2.0 }, scripts: { audit: npm audit, update: npm update } } // 运行命令 // npm run audit // npm run update毒舌点评这才叫前端安全让你的网站固若金汤再也不用担心黑客攻击了。