Laravel Sail环境下Passport登录端点无法正常工作的解决办法
问题解决方案
你的问题核心是Laravel Sail容器内发起内部Http请求导致的进程死锁:当你在登录接口里用Http::post调用自身的Passport令牌端点时,若配置的login_endpoint是localhost或127.0.0.1,请求会被限制在容器内部,当前处理请求的PHP进程会被占用,无法响应新的请求,最终导致所有路由挂起、应用假死。
以下是针对性的解决方案:
方案一:修正登录端点的容器网络地址
- 修改
.env配置,将Passport登录端点指向Sail容器的服务名(默认服务名为laravel.test):PASSPORT_LOGIN_ENDPOINT=http://laravel.test/oauth/token PASSPORT_CLIENT_ID=你的密码客户端ID PASSPORT_CLIENT_SECRET=你的密码客户端密钥 - 确保
config/services.php中的Passport配置读取该环境变量:'passport' => [ 'login_endpoint' => env('PASSPORT_LOGIN_ENDPOINT'), 'client_id' => env('PASSPORT_CLIENT_ID'), 'client_secret' => env('PASSPORT_CLIENT_SECRET'), ], - 验证本地
hosts文件是否存在127.0.0.1 laravel.test的映射(Sail启动时通常会自动添加,若没有可手动添加)。
方案二:跳过Http客户端,直接调用Passport底层方法
彻底避免内部Http请求,直接用Passport的授权逻辑生成令牌,性能更高也不会触发死锁:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Laravel\Passport\Bridge\PasswordGrant; use League\OAuth2\Server\AuthorizationServer; public function login(Request $request) { // 验证用户账号密码 if (!Auth::attempt(['email' => $request->username, 'password' => $request->password])) { return response()->json('Credential error.', 400); } $user = Auth::user()->load('roles'); $server = app(AuthorizationServer::class); $grant = $server->getGrantType('password'); // 生成访问令牌 $accessToken = $grant->respondToAccessTokenRequest( $request, $server->getResponseType(), $server->getAccessTokenRepository() ); return response()->json([ 'tokenInfo' => [ 'access_token' => $accessToken->getToken(), 'token_type' => 'Bearer', 'expires_in' => $accessToken->getExpiryDateTime()->getTimestamp() - time(), 'refresh_token' => $accessToken->getRefreshToken()?->getToken() ], 'userInfo' => $user ], 200); }
注意:需确保已通过
php artisan passport:client --password创建密码客户端,并将对应的ID和密钥配置到.env中。
辅助排查步骤
- 检查Passport数据库表是否完整:执行
php artisan migrate确保oauth_clients、oauth_access_tokens等表存在。 - 调整PHP-FPM进程数:若并发请求较多,可修改
docker-compose.yml中PHP服务的启动命令,增加进程数:php: command: start-container -F -O
内容的提问来源于stack exchange,提问作者Yusuf ÇAKIRCA
相关产品推荐
相关产品推荐

