用户点击链接时如何将localStorage存储的JWT认证令牌发送至后端
解决方案
你可以通过全局拦截锚点标签点击事件的方式实现需求,无需修改现有链接代码,仅需新增一段全局原生JS逻辑即可,以下是两种可直接落地的方案:
方案1:拦截跳转手动带请求头(最推荐,安全性更高)
该方案不会暴露令牌到URL、浏览器历史记录或服务端日志中,适配你使用localStorage存储令牌的要求:
- 全局绑定点击事件,过滤出内部站点跳转的
<a>标签,阻止默认跳转行为 - 从localStorage取出JWT令牌,手动发起带
Authorization请求头的GET请求 - 后端校验通过后,直接将返回的页面内容渲染到当前文档,同时修改地址栏地址匹配目标路径
代码示例:
document.addEventListener('click', function(e) { // 过滤点击对象,仅处理内部站点跳转的a标签 const targetA = e.target.closest('a'); if (!targetA) return; const href = targetA.getAttribute('href'); // 排除外部链接、通讯协议链接、页内锚点、下载链接等不需要带令牌的场景 if ( (href.startsWith('http') && !href.startsWith(window.location.origin)) || href.startsWith('mailto:') || href.startsWith('tel:') || href.startsWith('#') || targetA.hasAttribute('download') ) return; e.preventDefault(); // 替换为你存储JWT的localStorage key const token = localStorage.getItem('jwt_token'); if (!token) { window.location.href = '/login'; return; } fetch(href, { headers: { 'Authorization': `Bearer ${token}` }, credentials: 'same-origin' }).then(res => { if (res.status === 401) { window.location.href = '/login'; return; } return res.text(); }).then(html => { if (html) { // 渲染返回的页面内容 document.open(); document.write(html); document.close(); // 修改地址栏为目标路径 window.history.pushState({}, '', href); } }).catch(err => console.error('请求失败:', err)) })
方案2:令牌拼接为URL查询参数(仅适合低敏感场景)
如果你的系统敏感度较低,也可以用更简单的拼接参数方案,风险是令牌会明文出现在浏览器历史、服务端日志中:
document.addEventListener('click', function(e) { const targetA = e.target.closest('a'); if (!targetA) return; const href = targetA.getAttribute('href'); // 同方案1的过滤逻辑 if ( (href.startsWith('http') && !href.startsWith(window.location.origin)) || href.startsWith('mailto:') || href.startsWith('tel:') || href.startsWith('#') || targetA.hasAttribute('download') ) return; e.preventDefault(); const token = localStorage.getItem('jwt_token'); if (!token) { window.location.href = '/login'; return; } // 拼接令牌到查询参数 const targetUrl = new URL(href, window.location.origin); targetUrl.searchParams.set('jwt_token', token); window.location.href = targetUrl.toString(); })
后端Express侧可以直接从req.query.jwt_token中取出令牌做校验即可,注意校验完成后不要将令牌返回到页面源码中避免泄漏。
内容的提问来源于stack exchange,提问作者user152352
相关产品推荐
相关产品推荐

