在Laravel项目开发中,经常需要编写返回当前认证用户数据的API接口,这时候首先面临的问题就是路由该放在web.php还是api.php里。为了让大家更直观理解两种路由的差异,我们先看一张示意图:

web.php和api.php的核心差异
Laravel默认给两个路由文件配置了不同的中间件组,这是选择的核心依据:
- web.php绑定的是
web中间件组,默认包含StartSession、VerifyCsrfToken、EncryptCookies等处理会话、CSRF验证的组件,适合需要依赖浏览器会话、Cookie认证的Web页面请求。 - api.php绑定的是
api中间件组,默认只包含throttle:api限流中间件,没有会话和CSRF相关处理,更适合无状态的API请求,比如移动端、第三方调用的接口。
不同认证场景的选择方案
场景1:使用Session+Cookie的Web端认证
如果你的用户数据接口是给Web前端(比如Blade模板、传统多页应用)调用,且使用的是Laravel默认的Session认证,那么应该把路由放在web.php中,因为这类请求会自动携带浏览器的Cookie,web中间件组会自动解析会话拿到认证用户。
示例代码如下:
<?php
// routes/web.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\UserController;
// 使用web中间件组的auth中间件验证用户
Route::middleware(['auth'])->group(function () {
// 返回当前认证用户数据
Route::get('/user', [UserController::class, 'currentUser']);
});<?php
// app/Http/Controllers/UserController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function currentUser(Request $request)
{
// 直接通过request获取认证用户
return response()->json($request->user());
}
}场景2:使用Token/Passport/Sanctum的无状态API认证
如果你的接口是给移动端、第三方服务调用,使用的是Laravel Sanctum、Passport等Token认证方式,不需要依赖会话,那么应该把路由放在api.php中,避免不必要的会话处理开销。
示例代码如下(以Sanctum为例):
<?php
// routes/api.php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\UserController;
// 使用sanctum中间件验证Token
Route::middleware(['auth:sanctum'])->group(function () {
// 返回当前认证用户数据
Route::get('/user', [UserController::class, 'currentUser']);
});<?php
// app/Http/Controllers/Api/UserController.php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function currentUser(Request $request)
{
// 通过Token解析出认证用户
return response()->json($request->user());
}
}常见误区提醒
注意不要把依赖会话的Web接口放到api.php中,因为api.php默认没有启用会话中间件,会导致$request->user()无法获取到认证用户;也不要把无状态的Token认证接口放到web.php中,额外的会话、CSRF处理会降低接口性能,还可能引发CSRF验证失败的问题。总结
选择的核心逻辑是:依赖Session会话的Web端认证接口用web.php,无状态的Token类API认证接口用api.php。只要结合自己的认证方式和调用场景选择,就能避免绝大多数路由相关的问题。