Laravel Passport密码授权代码请求cURL超时问题求助
Laravel登录接口调用Passport /oauth/token出现cURL超时错误的解决方法
问题描述
通过Postman直接请求http://127.0.0.1:8000/oauth/token可以正常获取access token和refresh token,但在Laravel登录接口(/api/login)内部使用Http::asForm()->post调用同一地址时,触发cURL超时错误:
cURL error 28: Operation timed out after 30005 milliseconds with 0 bytes received for http://127.0.0.1:8000/oauth/token
登录接口代码如下:
public function login(LoginRequest $request): JsonResponse { if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) { $response = Http::asForm()->post(env('APP_URL') . '/oauth/token', [ 'grant_type' => 'password', 'client_id' => env('PASSPORT_PASSWORD_CLIENT_ID'), 'client_secret' => env('PASSPORT_PASSWORD_SECRET'), 'username' => $request->email, 'password' => $request->password, 'scope' => '', ]); $token = $response->json(); return response()->json([ 'success' => true, 'statusCode' => 200, 'message' => 'User has been logged successfully.', 'data' => $token, ], 200); } else { return response()->json([ 'success' => true, 'statusCode' => 401, 'message' => 'Unauthorized.', 'errors' => 'Unauthorized', ], 401); } }
预期返回结果:
{ "token_type": "Bearer", "expires_in": 1295999, "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIyIiwianRpIjoiYjdlM2U5ODFjYTFlZTU3OTQ1YWM3YjY0NmJlYzRhZmRiMmMxNjAyYzQyYzcwNzQ3YmI0MTM5OTI5ZDA0YjBlYjc4ZWM4NzlhZWRhNDFlOTEiLCJpYXQiOjE3MzcwMTI0MTAuMDA3NzY3LCJuYmYiOjE3MzcwMTI0MTAuMDA3NzcsImV4cCI6MTczODMwODQwOS45OTQ4MjUsInN1YiI6IjEiLCJzY29wZXMiOltdfQ.ppCR29LO0lJcqpPd8yxKueWqp1VNb8MJAeVI9lDzdvK8AcyfUR3SICJwbqGMTFO4mbl47E5bR7Iey24rRDUn", "refresh_token": "3532ca18dfabe19407b43237922b23aab97541dc56ceac59e56d01064cf6e602c6e77dbaa58d271f4b71554e3ad312d9bce68d83f8ec0c17fb2b96b4ce5be63dd1b940de900317ece48b45e076f7" }
解决方案
1. 直接使用Passport内置API生成token(推荐)
Laravel内置服务器(php artisan serve)是单进程模式,内部发起HTTP请求会阻塞当前请求,导致超时。直接调用Passport的用户模型方法生成token更高效,无需额外HTTP请求。
修改后的登录接口代码:
// 确保你的User模型已引入HasApiTokens trait // class User extends Authenticatable { use Laravel\Passport\HasApiTokens, ... } public function login(LoginRequest $request): JsonResponse { if (Auth::attempt(['email' => $request->email, 'password' => $request->password])) { $user = Auth::user(); // 生成access token及对应token实例 $tokenResult = $user->createToken('Login Token'); $accessToken = $tokenResult->accessToken; // 获取关联的refresh token ID $refreshToken = $tokenResult->token->id; return response()->json([ 'success' => true, 'statusCode' => 200, 'message' => 'User has been logged successfully.', 'data' => [ 'token_type' => 'Bearer', 'expires_in' => $tokenResult->token->expires_at->diffInSeconds(now()), 'access_token' => $accessToken, 'refresh_token' => $refreshToken ], ], 200); } else { return response()->json([ 'success' => true, 'statusCode' => 401, 'message' => 'Unauthorized.', 'errors' => 'Unauthorized', ], 401); } }
2. 改用多进程服务器(若坚持使用内部HTTP请求)
如果必须保留内部HTTP请求逻辑,需替换单进程的php artisan serve,改用Nginx+PHP-FPM这类多进程服务器,避免请求阻塞导致超时。
3. 校验环境变量配置
确认.env文件中的APP_URL、PASSPORT_PASSWORD_CLIENT_ID、PASSPORT_PASSWORD_SECRET配置准确,确保请求参数无错误。
内容的提问来源于stack exchange,提问作者SWAFWAN P P
相关产品推荐
相关产品推荐

