前端通过调用 /api/auth/check 接口(携带 credentials: 'include')校验登录态,根据返回的 logged 字段控制按钮 disabled 属性,但必须由后端二次验证权限且防重复提交。

怎么判断用户是否已登录(前端角度)
前端不能真正校验登录态,只能配合后端做界面层控制。常见做法是:页面加载时发一个 /api/user/session 请求,返回 { logged: true, uid: 123 } 或 { logged: false }。如果请求失败或返回 logged: false,就禁用按钮并提示“请先登录”。
注意:不要用 localStorage 是否存在 token 来判断——token 可能已过期,且没和后端 session 对齐。
- 必须走接口校验,哪怕只是 GET
/api/auth/check这类轻量端点 - 避免在 JS 里硬编码 token 字段名(比如
localStorage.getItem('jwt')),应由后端统一返回登录态字段 - 接口需带 credentials:
fetch('/api/auth/check', { credentials: 'include' }),否则 Cookie 不会发送
按钮禁用逻辑怎么写(原生 HTML + JS)
拿到登录态后,直接操作按钮的 disabled 属性和文案。别只改样式(比如加 opacity),必须设 disabled,否则仍可点击触发事件。
const cartBtn = document.querySelector('#add-to-cart');
fetch('/api/auth/check', { credentials: 'include' })
.then(r => r.json())
.then(data => {
if (data.logged) {
cartBtn.disabled = false;
cartBtn.textContent = '加入购物车';
} else {
cartBtn.disabled = true;
cartBtn.textContent = '请先登录';
}
});
- 按钮初始状态建议设为
disabled,等接口返回再更新,防止闪现可点击态 - 不要用
cartBtn.style.pointerEvents = 'none'替代disabled,它绕过表单约束,且无障碍不友好 - 如果按钮是动态渲染的(如商品列表循环生成),记得对每个按钮单独处理,别只查第一个
为什么不能只靠前端控制(权限绕过风险)
用户删掉 disabled 属性、用 Postman 直调加购接口、甚至重放抓包请求,都能绕过按钮限制。所以后端 /api/cart/add 接口必须二次校验 session 或 token,并返回 401 Unauthorized。
- 前端禁用只是体验优化,不是安全措施
- 后端校验必须独立于前端传来的任何字段(比如不要信前端传的
user_id),而应从 Cookie / Authorization header 解析并验证 - 如果后端返回 401,前端要捕获并跳转登录页,而不是静默失败
Vue/React 项目里怎么组织这个逻辑
在组件挂载时检查登录态,用响应式数据驱动按钮状态。重点是把校验逻辑抽成可复用函数,别每个按钮都写一遍 fetch。
// React 示例(useAuth hook)
const { isLoggedIn, isLoading } = useAuth();
return (
<button disabled isloading onclick="{handleAddToCart}">
{isLoading ? '检查中...' : isLoggedIn ? '加入购物车' : '请先登录'}
</button>
);
- 避免在
onClick里临时判断登录态——用户可能等接口返回才点,导致竞态 - 服务端渲染(SSR)场景下,首次加载需从服务端注入登录态,否则会有水合 mismatch
- 如果用 Pinia / Redux,把登录态存在 store 里,但记得每次页面切换仍要刷新(避免 stale state)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











