Cookie签名后怎么验证才安全?
我在用 Express 写登录功能,后端用 cookie-parser 签了名的 Cookie,但前端每次读取的时候都拿不到原始值,只看到带 .sig 的一串。我试过直接用 document.cookie 读,结果是加密后的,根本没法用。
是不是前端根本不该读这种签名 Cookie?那如果我想在前端判断用户是否登录,该怎么处理?后端签了名的 Cookie 到底是用来干啥的?
我现在的代码大概是这样:
app.use(cookieParser('my-secret-key'));
app.get('/login', (req, res) => {
res.cookie('userId', '123', { signed: true });
});
但浏览器里看到的是 userId=123; userId.sig=somehash...,前端完全不知道怎么验证这个签名是否有效,也不敢直接信任 userId=123 这部分。
cookie-parser签名的 Cookie 是为了确保数据在传输过程中不被篡改。前端拿到的userId.sig就是用来验证userId是否被篡改过的签名。前端确实不应该去读或验证这些签名,因为前端的安全性无法保证,很容易被攻击者利用。那么你想在前端判断用户是否登录,通常的做法是设置一个未签名的、简单的登录状态标识,比如一个
isLoggedIn或者authToken。你可以在登录时生成一个 token,这个 token 可以是 JWT(JSON Web Token),然后把这个 token 设置为一个未签名的 Cookie。前端通过检查这个 token 来判断用户是否登录。
不过更好的做法是让前端发送一个请求到后端,后端验证 session 或 token 后返回用户的登录状态。这样安全性更高,也不用担心前端存储的信息被篡改。
至于你现有的代码,可以稍微调整一下:
然后在前端,你可以简单地通过
document.cookie检查isLoggedIn是否存在且为true,但这只是一个基本的判断,并不安全,建议还是通过后端验证来确认用户身份。你理解错了,
userId=123就是原始值,明文的,谁都能看见。签名(.sig)的作用是让后端能检测这个123有没有被恶意改成456,前端既没必要也没能力验证。判断登录状态正确做法是写个接口让后端告诉你,比如:
前端调这个接口就行了,别瞎折腾在前端读 Cookie 验签名。