上周帮朋友改一个静态站点,急需他提了个需求:给某个页面加个密码框,求解输对了跳转到下载页,密码面跳输错了给个提示。验证听起来简单,并实但他之前找人写的现页代码直接用明文密码写在JS里,任何人右键查看源代码就能看到。急需他问我有没有稍微体面一点的求解方案。
先说清楚一件事:纯前端的密码面跳密码验证,本质上没有安全性可言。验证只要密码逻辑跑在浏览器里,并实有心人总能扒出来。现页但如果你的急需目的只是“别让随便点进来的人看到内容”,而不是求解对抗真正的攻击者,那用HTML+JS确实能应付。密码面跳
最粗暴的写法是这样:
<input type="password" id="pwd"> <button onclick="check()">进入</button> <script> function check(){ var v = document.getElementById('pwd').value; if(v === 'abc123'){ window.location.href = 'target.html'; } else { alert('密码错误'); } } </script> 这段代码能用,但问题很明显。密码暴露在源码里,而且alert弹窗体验很差。我朋友那个页面是给客户预览用的,弹个系统警告框显得特别业余。
稍微改进一下,可以把提示信息渲染到页面上,而不是用alert。再给回车键加个监听,用户体验会好很多:
<input type="password" id="pwd" placeholder="请输入访问密码"> <p id="msg" style="color:red;"></p> <button id="btn">确认</button> <script> var pwd = document.getElementById('pwd'); var msg = document.getElementById('msg'); var btn = document.getElementById('btn'); function verify(){ if(pwd.value === 'abc123'){ location.replace('target.html'); } else { msg.textContent = '密码不对,再试试'; pwd.value = ''; pwd.focus(); } } btn.addEventListener('click', verify); pwd.addEventListener('keydown', function(e){ if(e.key === 'Enter') verify(); }); </script> 这里用了location.replace而不是href,好处是跳转后用户按返回键不会回到密码页。对于“一次性通过”的场景,这个细节挺重要。
但密码还是明文。怎么办?可以做个简单的哈希。浏览器有原生的crypto API,用SHA-256把用户输入转成哈希值,再跟预设的哈希比对。这样源码里看不到原始密码:
async function sha256(str){ var buf = new TextEncoder().encode(str); var hash = await crypto.subtle.digest('SHA-256', buf); return Array.from(new Uint8Array(hash)) .map(b => b.toString(16).padStart(2,'0')).join(''); } async function verify(){ var h = await sha256(pwd.value); if(h === '预设的哈希值'){ location.replace('target.html'); } else { msg.textContent = '密码不对,再试试'; } } 你可以先在控制台算好密码的SHA-256值,把那个字符串硬编码进去。这样别人查看源码只能看到一个哈希,没法直接反推出密码。当然,理论上彩虹表能撞出来弱密码,但对付一般场景足够了。
还有一个坑要注意:如果你的页面是用file://协议直接打开的,crypto.subtle在某些浏览器里会返回undefined。必须走http或https才行。本地测试的话,起个简单的服务器,比如python -m http.server,就能解决。
另外,跳转目标页本身也得做点防护。如果target.html是公开可访问的,那别人直接输URL就绕过了密码页。纯静态方案没法根治这个问题,但可以加一层referrer检查,或者把目标内容也做一次轻量验证。真要安全,还是得上后端。
我最后给朋友的方案就是SHA-256哈希比对加location.replace,页面提示用DOM操作,回车键绑定。他看完说够用了,反正只是防同事误点,不是防黑客。这话说得实在——技术方案从来都是看场景的,脱离需求谈安全没意义。