如何在Laravel中基于session ID生成供浏览器扩展使用的身份验证token
Laravel 浏览器扩展身份校验Token实现方案
核心设计原则
- 严禁明文暴露原始Session ID到前端页面,避免会话被窃取伪造
- 前端输出的token仅携带非敏感的关联校验信息,不包含可直接用于伪造会话的内容
- 所有有效性校验必须结合请求携带的真实session Cookie完成,前端token无法单独通过校验
- Token和会话生命周期完全绑定,无需额外维护独立的token存储表
第一步:自动生成带签名的关联Token
- 创建专属中间件
InjectExtensionAuthToken,将其挂载到web中间件组下,确保执行时session已经完成初始化 - 中间件内的token生成逻辑严格遵循签名规则,不泄露原始session值,核心代码如下:
// 获取当前会话核心标识(服务端内部使用,不输出到前端) $currentSessionId = session()->getId(); $currentUserId = auth()->id() ?? 0; // 复用会话自身的过期时间,无需单独计算时效 $sessionExpireAt = now()->addMinutes(config('session.lifetime'))->timestamp; // 用应用秘钥生成不可逆的HMAC签名,无法被前端篡改 $signature = hash_hmac( 'sha256', $currentSessionId . '|' . $currentUserId . '|' . $sessionExpireAt, config('app.key') ); // 组装可输出到前端的轻量token,仅携带校验必要的非敏感信息 $extensionToken = base64_encode(json_encode([ 'uid' => $currentUserId, 'exp' => $sessionExpireAt, 'sig' => $signature ])); // 将token共享给所有视图,无需每个页面单独传参 View::share('extensionAuthToken', $extensionToken);
第二步:将Token注入页面Head区域
在全局布局模板的</head>闭合标签前,添加meta标签输出token,浏览器扩展可直接通过DOM选择器提取内容:
<meta name="extension-auth-token" content="{{ $extensionAuthToken ?? '' }}">
第三步:编写服务端Token校验逻辑
当浏览器扩展携带token向Laravel发请求时,通过自定义校验规则完成有效性判断:
- 接收请求传来的token,先做base64解码,拆分出
uid、exp、sig三个字段 - 第一校验环节:判断
exp时间戳是否早于当前服务器时间,超时直接返回会话已过期 - 第二校验环节:从请求自带的session cookie中读取当前真实的session ID,按照生成token时的相同规则,重新计算HMAC签名值
- 第三校验环节:将重新计算的签名值和请求带来的
sig字段做比对,同时确认当前会话存储的用户ID和token携带的uid字段是否一致 - 所有校验通过才允许扩展的请求访问对应接口,任意环节不匹配直接返回未授权
常见踩坑点
- 不要在
AppServiceProvider的boot方法中直接生成token,该阶段web中间件尚未执行,session还未完成初始化,无法获取正确的会话ID - 不要直接复用Laravel自带的CSRF token作为扩展校验凭证,CSRF token仅用于防跨站表单提交,无法直接关联判断会话是否过期、是否有效
- 配置CORS规则时,需放行浏览器扩展的请求来源,同时将session cookie的
same_site属性调整为和扩展运行场景匹配的值,确保扩展发请求时能正确携带session cookie
内容的提问来源于stack exchange,提问作者Mouse
相关产品推荐
相关产品推荐

