两个Laravel项目通过Sanctum API通信异常问题求助
问题根源排查与解决步骤
1. 先把Sanctum的数据库连接指定正确
Sanctum默认用Laravel配置里的默认数据库连接,没单独给它指定连接的话,肯定会出现串库问题。
针对Bac4(Laravel 8):
如果Bac4是提供API的服务端,得保证它的Sanctum用自己的数据库:
- 打开
config/sanctum.php,如果没有connection配置项,添加一行:'connection' => 'mysql', // 填Bac4自己的数据库连接名,对应你在database.php里配置的连接 - 同时,Bac4的
User模型和Sanctum的token模型(PersonalAccessToken)也要指定连接:
在App\Models\User里添加:
Sanctum的protected $connection = 'mysql'; // 绑定Bac4的数据库PersonalAccessToken默认在vendor目录,你可以发布到本地修改:
然后在php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" --tag="sanctum-models"App\Models\PersonalAccessToken里添加:protected $connection = 'mysql';
针对InfraProject(Laravel 9):
如果InfraProject是调用Bac4 API的客户端,它不需要存储Bac4的token,直接把请求发去Bac4,让Bac4自行验证即可。但如果InfraProject本身也是服务端,需要接收Bac4的请求并验证其token,那得这么配置:
- 先在
config/database.php里添加Bac4的数据库连接:'bac4_mysql' => [ 'driver' => 'mysql', 'host' => env('BAC4_DB_HOST', '127.0.0.1'), 'port' => env('BAC4_DB_PORT', '3306'), 'database' => env('BAC4_DB_DATABASE', 'bac4'), 'username' => env('BAC4_DB_USERNAME', 'root'), 'password' => env('BAC4_DB_PASSWORD', ''), // 其他配置参照你本地的数据库参数填写 ], - 然后创建自定义的Sanctum守卫,指定使用Bac4的连接:
在config/auth.php的guards数组里添加:
同时在'bac4_sanctum' => [ 'driver' => 'sanctum', 'provider' => 'bac4_users', ],providers数组里添加Bac4的用户提供者:'bac4_users' => [ 'driver' => 'eloquent', 'model' => App\Models\Bac4User::class, // 需要创建对应Bac4用户表的模型 ], - 新建
App\Models\Bac4User模型,指定连接:namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; use Laravel\Sanctum\HasApiTokens; class Bac4User extends Authenticatable { use HasApiTokens; protected $connection = 'bac4_mysql'; protected $table = 'users'; // 对应Bac4的users表名 // 添加必要的$fillable或$guarded属性 } - 最后,需要验证Bac4 token的路由使用这个自定义守卫:
Route::middleware('auth:bac4_sanctum')->get('/some-api', function () { // 你的业务逻辑 });
2. 明确登录API的归属与逻辑
你提到用InfraProject的凭证能生成token,这说明登录API的逻辑串库了:
- 先确认登录API属于Bac4,且登录时查询的是Bac4数据库里的用户:
在Bac4的登录控制器里,确保查询用户用的是绑定了Bac4连接的User模型:$user = App\Models\User::where('email', $request->email)->first(); // 这个User模型已经指定了Bac4的数据库,所以会查询Bac4的用户数据 - 如果登录API部署在InfraProject里,那生成的token本来就会存在InfraProject的数据库,这和你俩项目互访的需求完全矛盾——得先明确:谁是提供API、存储token的服务端,谁是调用API、持有token的客户端。
3. 别混淆中间件的用途
你配置了EnsureFrontendRequestsAreStateful中间件,这个是给同域SPA场景用的,两个独立后端项目互访应该用无状态API:要么移除这个中间件,要么确保请求头里携带正确的Authorization: Bearer {token},不要依赖session。
- 跨项目调用API时,客户端(比如InfraProject)发送请求必须携带
Authorization头,值为Bearer加上Bac4生成的token。 - 服务端(Bac4)的API路由要使用
auth:sanctum中间件,且保证Sanctum用自己的数据库验证token。
4. 验证数据库连接的正确性
在两个项目里分别执行以下代码,确认查询的是正确的数据库:
// 在Bac4里执行,检查是否查询到自己的users表数据 dd(App\Models\User::first()); // 在InfraProject里执行,若查询Bac4用户则用Bac4User模型 dd(App\Models\Bac4User::first());
如果查询结果不符合预期,说明.env里的数据库参数或连接配置有误,需要修正。
内容的提问来源于stack exchange,提问作者Rex Zednelab
相关产品推荐
相关产品推荐

