Laravel10升级后v2认证API端点无响应(Socket hang up)问题
问题概述
升级Laravel至v10、Passport至v11并将PHP版本升级至8.2后,普通API端点(如/api/user)正常工作,但所有使用auth:api_v2中间件的v2版本API端点(如/api/v2/user)无响应,仅返回Socket hang up错误。请求未进入控制器处理方法,最后执行的代码为Kernel中的Pipeline调度逻辑。
核心排查与解决方案
根据现象(未认证的v2端点正常,认证的端点挂掉),问题大概率出在Passport与v2用户模型的集成或PHP8.2兼容性上,以下是具体解决步骤:
1. 验证V2 User模型的Passport集成
确保App\Models\V2\Base\User模型正确引入并使用Passport的必要Trait,这是Passport认证的基础:
<?php namespace App\Models\V2\Base; use Illuminate\Foundation\Auth\User as Authenticatable; use Laravel\Passport\HasApiTokens; use Illuminate\Notifications\Notifiable; use Illuminate\Database\Eloquent\Factories\HasFactory; class User extends Authenticatable { // 必须引入HasApiTokens trait,否则Passport无法识别该模型 use HasApiTokens, HasFactory, Notifiable; // 确保填充字段或 guarded 属性正确配置,避免模型实例化失败 protected $fillable = [ 'name', 'email', 'password', // 其他业务字段 ]; // PHP 8.2默认禁用动态属性,如果模型使用未定义的属性,需添加此注解 // #[AllowDynamicProperties] }
若遗漏HasApiTokens,Passport无法完成认证流程,会触发致命错误导致请求中断,进而出现Socket hang up。
2. 修复API版本中间件的无用逻辑
你的APIVersion中间件中定义了$apiVersion变量但未实际使用,存在未完成的逻辑,可能干扰后续认证流程。简化中间件代码:
public function handle(Request $request, Closure $next, $guard) { config(['app.api.version' => $guard]); // 移除未使用的$apiVersion相关代码,避免不必要的变量定义干扰 return $next($request); }
认证模型的切换已通过路由中指定的auth:api_v2 guard完成,无需额外修改。
3. 确认Passport Guard配置正确性
再次核对config/auth.php中的配置,确保api_v2 guard与users_v2 provider完全匹配,使用完整类名避免命名空间解析错误:
'guards' => [ // ...其他guard配置 'api_v2' => [ 'driver' => 'passport', 'provider' => 'users_v2', ], ], 'providers' => [ // ...其他provider配置 'users_v2' => [ 'driver' => 'eloquent', 'model' => App\Models\V2\Base\User::class, ], ],
4. 排查PHP 8.2兼容性问题
PHP 8.2默认禁用动态属性,若V2 User模型或关联代码中使用了未声明的属性,会触发ErrorException,若错误未被捕获会导致请求异常终止:
- 检查模型中所有使用的属性是否均已声明
- 若必须使用动态属性,在模型类上添加
#[AllowDynamicProperties]注解
5. 清除缓存并开启详细日志
升级后缓存可能残留旧配置,执行以下命令清除缓存:
php artisan cache:clear php artisan config:clear php artisan route:clear php artisan view:clear
同时修改.env文件开启详细错误日志:
APP_DEBUG=true LOG_LEVEL=debug
查看storage/logs/laravel.log,里面会记录请求中断前的具体错误信息(如Trait缺失、模型字段错误等),这是定位问题的关键。
6. 重新生成Passport密钥(可选)
若以上步骤无效,尝试重新生成Passport密钥,确保密钥与当前版本兼容:
php artisan passport:install
内容的提问来源于stack exchange,提问作者Mike_NotGuilty

