JS判断用户是否登陆登陆
作者:综合 来源:探索 浏览: 【大 中 小】 发布时间:2026-10-17 06:09:50 评论数:
打开任何一个后台管理系统,判断第一件事就是用户判断用户有没有登录。没登录就踢到登录页,否登登录了就放行。陆登陆这个逻辑简单到不值一提,判断但真动手写的用户时候,细节比想象中多。否登
最直接的陆登陆做法:后端在用户登录成功后,往浏览器写一个 Cookie,判断比如 session_id=abc123。用户前端 JS 只需要检查这个 Cookie 存不存在。否登
function isLoggedIn() { return document.cookie.includes('session_id'); } 三行代码,陆登陆完事。判断但这里有个坑——document.cookie 拿不到 HttpOnly 标记的用户 Cookie。如果你的否登后端把 session_id 设成了 HttpOnly(出于安全考虑,通常都该这么做),那前端 JS 根本读不到它。我第一次踩这个坑的时候,对着控制台愣了半天:Network 面板里明明有 Cookie,JS 就是读不出来。
所以纯前端判断登录状态,靠读 Cookie 这条路,在 HttpOnly 面前走不通。
换个思路。前端不直接判断“有没有登录”,而是问后端“我登录了没”。页面加载时发一个请求:
fetch('/api/check-auth', { credentials: 'include' }) .then(res => res.json()) .then(data => { if (!data.loggedIn) { window.location.href = '/login'; } }); 这个方案的好处是,判断逻辑完全在后端。后端根据 session 或 token 返回 true/false,前端只管跳转。HttpOnly 的问题也不存在了,因为 Cookie 是浏览器自动带上的,JS 不需要读它。
但这样每次页面加载都多一个请求。用户从列表页跳到详情页,路由一变就查一次,体验上会有一瞬间的白屏或者闪烁。我的做法是在 sessionStorage 里缓存一个标记:
// 登录成功后 sessionStorage.setItem('logged_in', '1'); // 路由守卫里 function checkAuth() { if (sessionStorage.getItem('logged_in') !== '1') { window.location.href = '/login'; return false; } return true; } 这解决了闪烁问题,但引入了新问题:用户手动清掉 sessionStorage 怎么办?或者 session 在后端过期了,前端还以为是登录状态?
我的处理方式是双保险。前端用 sessionStorage 做快速判断,避免每次路由跳转都发请求。同时,任何 API 请求返回 401 状态码时,立即清除 sessionStorage 并跳转登录页。这样即使前端标记过期了,第一个失败的请求就会触发纠正。
async function request(url, options) { const res = await fetch(url, options); if (res.status === 401) { sessionStorage.removeItem('logged_in'); window.location.href = '/login'; throw new Error('Unauthorized'); } return res; } 这套组合拳打下来,实际项目中基本够用。纯前端判断登录状态,本质上是个伪命题——登录状态存在后端,前端只能缓存一个“影子”。影子和本体不同步的时候,以本体为准。401 就是本体在说话。
还有个小细节。有些项目用 localStorage 存 token,然后判断 token 是否存在。这比 sessionStorage 更持久,关闭标签页再打开还在。但 localStorage 不会自动过期,用户登出后如果没清干净,下次打开还是登录态。我见过一个后台,用户点了退出,刷新页面又进去了,查了半天发现是 localStorage 里的 token 没删。所以登出的时候,该清的都要清:
function logout() { localStorage.removeItem('token'); sessionStorage.clear(); window.location.href = '/login'; } 判断登录这件事,代码量不大,但涉及到 Cookie 属性、存储选择、请求拦截、状态同步这些点。写的时候多想想边界情况,比事后修 bug 省事得多。
