
本文介绍如何通过自定义 sanctum 的 `personalaccesstoken` 类,实现对指定手机号(如 0900 000 00 00)用户的无认证放行,既保留整体 api 的 `auth:sanctum` 安全性,又满足特殊调试或白名单场景需求。
Laravel Sanctum 默认采用严格的令牌校验机制,一旦启用 auth:sanctum 中间件,所有请求均需携带有效 Personal Access Token。但实际开发中,常需为特定内部账号(如测试管理员、运维账号)临时豁免认证——不推荐移除中间件或添加路由例外(易遗漏、难维护),而应从认证源头干预。
Sanctum 提供了高度可扩展的设计:其核心校验逻辑最终委托给 PersonalAccessToken::findToken() 方法。我们可通过继承并重写该方法,在令牌解析阶段动态判断当前请求是否应跳过认证。
✅ 实现步骤
-
创建自定义 Token 模型
在 app/Models 目录下新建 CustomPersonalAccessToken.php:
hasHeader('X-Whitelist-Bypass')
&& $request->header('X-Whitelist-Bypass') === 'true';
if ($isWhitelistedUser && $request->has('telephone') && $request->has('password')) {
$user = \App\Models\User::where('telephone', $request->telephone)
->where('password', bcrypt($request->password)) // ⚠️ 生产环境请勿明文比对!见下方说明
->first();
if ($user && $user->telephone === '0900 000 00 00') {
// 模拟“认证通过”:返回一个空但非 null 的 token 实例
// 注意:此对象不会被持久化,仅用于绕过中间件校验
return new static(['tokenable_id' => $user->id, 'tokenable_type' => get_class($user)]);
}
}
}
return $tokenModel;
}
}-
配置 Sanctum 使用自定义模型
在 config/sanctum.php 中更新模型路径:
'models' => [
'personal_access_token' => \App\Models\CustomPersonalAccessToken::class,
],-
注册服务提供者(Laravel
确保 config/app.php 的 providers 数组包含:Laravel\Sanctum\SanctumServiceProvider::class,
(Laravel 10+ 已自动发现)
客户端调用方式(示例)
对于白名单用户,前端需在请求头中显式声明并携带凭证(仅限可信内网/调试环境):
curl -X GET "http://your-app.test/api/packages" \ -H "X-Whitelist-Bypass: true" \ -d "telephone=0900 000 00 00" \ -d "password=123456"
⚠️ 重要安全提醒 上述示例中直接传入 password 并做 bcrypt() 比对存在严重风险,生产环境严禁使用。正确做法是: ✅ 使用独立的 api_token 字段(如 whitelist_api_key)替代密码; ✅ 或通过已登录 Session + IP 白名单 + 时间窗口三重校验; ✅ 或改用 Laravel 的 Auth::onceBasic() 结合自定义 Guard 实现更安全的混合认证。 X-Whitelist-Bypass 头必须由反向代理(如 Nginx)或网关层过滤,禁止公网直接访问。 此方案本质是「认证逻辑前置」,而非「跳过中间件」,因此仍受 CSRF、速率限制等其他中间件保护。
✅ 替代方案建议(更推荐)
若仅需开发期快速验证,可考虑以下更安全、更易维护的方式:
-
使用 Sanctum 的 guard 配置分离认证流
在 config/auth.php 中新增 sanctum_whitelist guard,绑定专用 Provider,专用于白名单用户; -
在中间件中注入条件判断(无需修改 Sanctum 源码)
创建 BypassSanctumForWhitelist 中间件,置于 auth:sanctum 前,提前拦截并 Auth::login($user); -
利用 Laravel 的 Route::middleware() 动态绑定
改写路由组为条件式注册(需配合服务容器解析)。
总之,Sanctum 的可扩展性使其支持精细的认证策略定制。关键在于:始终将安全边界前移,避免在业务逻辑中修补认证漏洞,而应在认证模型与中间件层完成职责隔离。










