如何检测Laravel Auth Sanctum令牌的不可用或未认证状态(移动端API)
解决Laravel Sanctum令牌吊销后API返回登录页HTML的问题
问题本质
当auth:sanctum中间件验证失败时,Laravel默认会把请求重定向到Web登录页面,但你的移动端API需要的是JSON格式的未认证提示,这就是你收到HTML响应的原因。
正确处理方案
1. 自定义API认证异常响应
修改app/Exceptions/Handler.php中的异常处理逻辑,让API路由在认证失败时返回JSON:
use Illuminate\Auth\AuthenticationException; use Illuminate\Http\Request; public function register() { $this->renderable(function (AuthenticationException $e, Request $request) { // 匹配所有API前缀的路由 if ($request->is('api/*')) { return response()->json([ 'message' => '未认证,请提供有效的访问令牌' ], 401); } }); }
这样一来,只要是API路由的认证失败请求,都会返回标准的401状态码和JSON提示,不会再返回登录页HTML。
2. 纠正你的令牌检测尝试
你试过的两种方法都不适合当前场景:
Auth::attempt($credentials):这个方法是给Session认证用的,它验证的是用户账号密码并创建会话,和Sanctum的令牌认证完全是两套机制,所以不管有没有有效令牌,它都会返回false,别用在API令牌验证上。- 手动查询
personal_access_tokens表:如果$request->user()能拿到用户实例,说明auth:sanctum中间件已经确认了令牌的有效性(存在、未过期),这时候再查令牌表完全是多余的。而如果令牌已经被吊销,中间件会直接抛出认证异常,根本到不了控制器里的检测代码。
3. 优化令牌吊销逻辑
你现在用$request->user()->tokens()->delete();会删掉当前用户的所有令牌,如果需要只吊销当前正在使用的令牌,可以改成:
// 删除当前请求对应的令牌 $request->user()->currentAccessToken()->delete(); // 或者按令牌名称删除 $request->user()->tokens()->where('name', $tokenName)->delete();
总结
- 解决返回HTML的核心是修改异常处理器,适配API路由的响应格式。
- 不需要在控制器里手动验证令牌,
auth:sanctum中间件已经帮你做了这件事。 - 令牌吊销后,再次请求API会触发认证异常,此时通过自定义异常响应返回JSON提示即可。
内容的提问来源于stack exchange,提问作者Muhammad Faisal
相关产品推荐
相关产品推荐

