PHP集成Google与Facebook第三方登录代码冲突问题求助
冲突根源
- 两个平台OAuth2回调都复用相同的
$_GET['code']参数触发逻辑,回调时谷歌返回的授权码会被Facebook登录逻辑误处理,反之亦然,直接触发未捕获异常导致500错误 - 两个登录逻辑都使用
$_SESSION['access_token']存储授权令牌,后执行的代码会覆盖先执行的代码存储的令牌,导致获取用户信息时令牌不匹配,无法拉取数据 - 公共用户信息字段(user_id/user_name等)如果有业务需要区分平台也建议做前缀区分,统一账号体系可以保留,不影响核心功能运行
修复方案
- 给两个平台的授权跳转redirect_uri追加平台标识参数,谷歌回调地址加
&platform=google,Facebook回调地址加&platform=facebook,注意要和对应平台开发者后台配置的回调地址规则匹配 - 区分会话中存储的授权令牌键名,避免相互覆盖
- 执行登录逻辑前先判断当前回调对应的平台,只执行对应平台的处理代码
修复后完整代码
// 先初始化$google_client、$facebook实例的原有逻辑保持不变,此处省略 // GOOGLE登录逻辑 if(isset($_GET['code']) && $_GET['platform'] == 'google') { $token = $google_client->fetchAccessTokenWithAuthCode($_GET["code"]); if (!isset($token['error'])) { $google_client->setAccessToken($token['access_token']); // 存储谷歌专属令牌,避免覆盖 $_SESSION['google_access_token'] = $token['access_token']; $google_service = new Google_Service_Oauth2($google_client); $data = $google_service->userinfo->get(); if (!empty($data['sub'])) { $_SESSION['user_id'] = $data['sub']; } if (!empty($data['given_name'])) { $_SESSION['user_name'] = $data['given_name'] . " " . $data['family_name']; } if (!empty($data['email'])) { $_SESSION['user_email_address'] = $data['email']; } if (!empty($data['picture'])) { $_SESSION['user_image'] = $data['picture']; } } } // FACEBOOK登录逻辑 $facebook_helper = $facebook->getRedirectLoginHelper(); if(isset($_GET['code']) && $_GET['platform'] == 'facebook') { if (isset($_SESSION['fb_access_token'])) { $access_token = $_SESSION['fb_access_token']; } else { $access_token = $facebook_helper->getAccessToken(); // 存储FB专属令牌,避免覆盖 $_SESSION['fb_access_token'] = $access_token; $facebook->setDefaultAccessToken($_SESSION['fb_access_token']); } $graph_response = $facebook->get("/me?fields=name,email", $access_token); $facebook_user_info = $graph_response->getGraphUser(); if (!empty($facebook_user_info['id'])) { $_SESSION['user_image'] = 'http://graph.facebook.com/' . $facebook_user_info['id'] . '/picture'; } if (!empty($facebook_user_info['id'])) { $_SESSION['user_id'] = $facebook_user_info['id']; } if (!empty($facebook_user_info['name'])) { $_SESSION['user_name'] = $facebook_user_info['name']; } if (!empty($facebook_user_info['email'])) { $_SESSION['user_email_address'] = $facebook_user_info['email']; } } else { // 生成FB登录地址时追加platform参数 $facebook_permissions = ['email']; $facebook_login_url = $facebook_helper->getLoginUrl('https://2goe.com/demo/'.$lang.'/home/?platform=facebook', $facebook_permissions); } // 生成谷歌登录地址时同样要追加platform参数,示例如下: // $google_login_url = $google_client->createAuthUrl() . '&platform=google';
额外注意事项
- 谷歌开发者后台配置的回调地址需要允许追加
platform参数,或直接把带参数的地址配置到后台白名单 - 上线前建议开启PHP错误日志排查,避免遗漏权限、类加载等非冲突类问题
内容的提问来源于stack exchange,提问作者Pokrowsky
相关产品推荐
相关产品推荐

