如何用Inertia向auth:api中间件路由发请求?能否共存双中间件?
问题解决思路
1. Inertia请求不带Authorization头的原因
Inertia 默认基于 Laravel 的 web 会话认证机制工作,它不会自动为请求添加 Authorization 头——这是 auth:api 中间件期望的认证方式(通常是 Bearer Token)。你直接用 get(route('api.me')) 发起请求时,只会带上 web 会话的 Cookie,不会携带 API Token,所以会被 auth:api 拦截。
2. 关于同时使用auth和auth:api中间件
可以让路由同时挂载这两个中间件,但要注意逻辑合理性:直接同时挂载会要求用户同时通过两种认证,这显然不符合需求。更实用的是让路由支持任意一种认证方式,具体实现有两种思路:
方式一:用auth中间件支持多Guard(推荐)
Laravel 的 auth 中间件允许指定多个 Guard,用户只要通过其中一个即可访问路由:
Route::get('/me', [UserController::class, 'me']) ->middleware('auth:web,api') ->name('api.me');
这里 web 是默认会话 Guard,api 是 Token Guard,无论用户是通过 Inertia 的 web 会话,还是携带 API Token,都能正常访问该路由。
方式二:同时挂载中间件(需调整逻辑)
如果一定要同时写两个中间件,需要自定义中间件逻辑让用户满足任意一种认证即可,否则默认会要求双重认证:
// 自定义中间件示例 class AllowWebOrApiAuth { public function handle(Request $request, Closure $next) { if (Auth::guard('web')->check() || Auth::guard('api')->check()) { return $next($request); } return abort(401); } } // 路由中使用自定义中间件 Route::get('/me', [UserController::class, 'me']) ->middleware(AllowWebOrApiAuth::class) ->name('api.me');
3. 若坚持用auth:api,让Inertia带Authorization头的方法
如果不想修改路由中间件,也可以手动给 Inertia 请求添加头:
单个请求添加头
get(route('api.me'), {}, { headers: { 'Authorization': `Bearer ${你的ApiToken}` } });
全局配置所有Inertia请求带头发送
在 Inertia 启动文件(比如 resources/js/app.js)中设置:
import { Inertia } from '@inertiajs/inertia'; Inertia.on('start', (event) => { // 从localStorage或页面共享数据中获取Token const token = localStorage.getItem('api_token'); if (token) { event.detail.headers['Authorization'] = `Bearer ${token}`; } });
内容的提问来源于stack exchange,提问作者TylerMills
相关产品推荐
相关产品推荐

