Laravel Socialite Twitter登录报错:缺少必填参数code_verifier
错误详情
{"message":"Error occuredies","data":"Client error: `POST https://api.twitter.com/2/oauth2/token` resulted in a `400 Bad Request` response:\n{\"error\":\"invalid_request\",\"error_description\":\"Missing required parameter [code_verifier].\"}\n113"}
前端实现(Vue.js)
登录按钮代码
<v-btn :size="!isSmall ? '40' : '50'" variant="text" style="background: #1c96e8" color="white" icon="mdi-twitter" @click="loginSocial('twitter-oauth-2')" />
登录请求方法
axios .get(`/gypsy-login/${social_name}`) .then((response) => { console.log(response); if (response) { window.location.assign(response.data.target_url); } else { window.location.href = "/sign-in"; } console.log(response.data.target_url); }) .catch((error) => { console.log(error); window.location.href = "/sign-in"; });
Laravel后端配置
.env配置
TWITTER_CLIENT_ID=someID TWITTER_CLIENT_SECRET=Some Secrect TWITTER_URL=https://admin.mysite.com/api/gypsy-login/twitter-oauth-2/callback
config/services.php配置
'twitter-oauth-2' => [ 'client_id' => env('TWITTER_CLIENT_ID'), 'client_secret' => env('TWITTER_CLIENT_SECRET'), 'redirect' => env('TWITTER_URL'), ],
控制器代码
跳转授权页方法
public function redirectToProvider($provider) { try { return response()->json([ 'target_url' => Socialite::driver($provider)->stateless()->redirect()->getTargetUrl(), ]); } catch(\Exception $ex) { return response()->json([ 'message' => 'Error occured twitter', 'data' => $ex->getMessage().$ex->getLine() ], 500); } }
回调处理方法(错误触发位置)
public function handleProviderCallback($provider) { try { $user = Socialite::driver($provider)->stateless()->user(); $environment = env('APP_ENV'); $currentDate = Carbon::now()->format('d/m/Y'); if ($environment === 'production') { $url = 'https://admin.mysite.com'; } else { $url = 'http://127.0.0.1:3000'; } if ($provider == 'google' || $provider == 'linkedin-openid' || $provider == 'facebook' || $provider == 'twitter-oauth-2') { $gypsyExists = GypsyMaster::where('email_id', $user->email)->first(); if($gypsyExists) { $gypsyId = $gypsyExists->gypsy_id; $username = $gypsyExists->email_id; $token = $gypsyExists->generateToken($gypsyId, $username); $gypsyExists->token = $token; $gypsyExists->last_login = $currentDate; $gypsyExists->save(); return redirect($url.'/?social=' . $provider . '&token=' . $token); } else { return redirect($url.'/social-sign-up?social=' . ucwords($provider) . '&token=' . $user->token.'&name='.$user->name.'&avatar='.$user->avatar_original.'&email='.$user->email); } } } catch(\Exception $ex) { return response()->json([ 'message' => 'Error occuredies', 'data' => $ex->getMessage().$ex->getLine() ], 500); } }
问题现状
点击登录按钮可正常跳转至Twitter授权页,但点击「授权此应用」后触发回调时出现上述错误。已成功实现Google、Facebook、LinkedIn的Socialite登录,唯独Twitter登录出现该问题。
解决思路
- PKCE流程适配:Twitter OAuth2强制要求PKCE验证,
stateless()模式下Socialite无法在会话中存储code_verifier参数,导致回调时缺失该参数。 - 调整会话模式:
- 尝试移除
redirectToProvider和handleProviderCallback中的stateless(),改用有状态会话。同时配置跨域会话(如设置SESSION_DOMAIN),让后端保留PKCE相关验证数据。 - 若必须保持无状态,需手动处理PKCE流程:生成授权URL时创建
code_verifier和code_challenge,前端跳转时携带唯一标识,回调时通过标识获取code_verifier并传递给Socialite。
- 尝试移除
- 版本检查:确保Laravel Socialite为最新稳定版,旧版本可能对Twitter OAuth2的PKCE支持不完善。
- 回调URL一致性验证:确认Twitter开发者平台配置的回调URL与后端
.env、config/services.php中的redirect地址完全一致,包括协议、域名、路径。
内容的提问来源于stack exchange,提问作者Muhammad Khan
相关产品推荐
相关产品推荐

