Laravel Sanctum鉴权时自动重定向至登录页问题求助
兄弟,我太懂你这个糟心的问题了!之前用Sanctum做纯后端SPA的时候,也踩过一模一样的坑——明明配置了JSON请求头,带了Bearer令牌,结果还是被莫名其妙重定向到登录页,甚至还得被迫写个没用的login路由,不然直接报错,简直离谱。
我给你梳理几个核心的排查和解决步骤,亲测有效:
1. 先确认你的路由放对地方了吗?
Laravel的web.php和api.php路由是完全不同的中间件组:web.php默认走的是传统Web应用的中间件,会自动处理会话、重定向这些;而api.php的路由默认挂载了api中间件组,专门处理API请求,不会随便重定向。
你现在的/checktoken路由如果是放在web.php里的,那肯定会触发重定向逻辑!赶紧把所有需要Sanctum鉴权的API路由都移到routes/api.php里,比如:
// routes/api.php Route::get('/checktoken', function () { info('ok'); return('token is ok'); })->middleware('auth:sanctum');
2. 强制Laravel在认证失败时返回JSON,而不是重定向
Laravel默认的认证失败处理逻辑是为传统Blade应用设计的,不管你有没有加JSON头,只要没正确配置,它就会优先重定向。我们需要修改异常处理器,让它识别API请求并返回JSON:
打开app/Exceptions/Handler.php,找到unauthenticated方法(如果你的文件里没有这个方法,就从父类继承过来),改成下面这样:
protected function unauthenticated($request, \Illuminate\Auth\AuthenticationException $exception) { // 如果请求期望JSON响应(比如带了Accept: application/json头) if ($request->expectsJson()) { return response()->json(['message' => '未授权访问,请先登录'], 401); } // 非API请求才走重定向逻辑 return redirect()->guest($exception->redirectTo() ?? route('login')); }
这样一来,只要你的Axios请求带了Accept: application/json,认证失败时就会返回401的JSON响应,再也不会跳登录页了,那个没用的login路由也可以删掉了!
3. 检查你的Axios配置和令牌有效性
你的Axios代码看起来没问题,但还是要确认几个细节:
- 打开浏览器开发者工具的「Application」标签,看看
localStorage里的auth_token是不是真的存在,有没有过期? - 发送请求时,去「Network」标签看请求头,确认
Authorization: Bearer xxx和Accept: application/json这两个头是不是都正确带上了?有时候令牌为空或者格式错了(比如少了Bearer前缀),都会触发认证失败。
4. 确认CORS和Sanctum的跨域配置没毛病
跨域配置错了也可能导致奇怪的问题:
- 打开
config/cors.php,确保你的SPA域名在allowed_origins里,比如你的SPA跑在http://localhost:3000,就加进去:
'allowed_origins' => ['http://localhost:3000'],
- 打开
config/sanctum.php,把SPA域名加到stateful数组里,比如:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( '%s%s', 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : '' ))),
按这几步走下来,应该就能解决重定向的问题了!如果还是不行,你可以再检查一下令牌是不是通过正确的方式获取的(比如用Sanctum的登录接口生成的,而不是自己随便造的)。
内容来源于stack exchange

