Я пытаюсь настроить HybridAuth, и я нахожусь на самых ранних стадиях. Прямо сейчас все, что я хочу сделать, это подключиться и убедиться, что HA перенаправит на facebook и предложит установку приложения, а затем аутентифицирует пользователя, когда вернется.
Я вручную вызываю следующее: http://mydomain.com/auth.php?provider=Facebook
auth.php выглядит так:
session_start(); require_once($_SERVER['DOCUMENT_ROOT'] . "/func/db_connect.php"); require_once($_SERVER['DOCUMENT_ROOT'] . "/api/auth/Hybrid/Auth.php"); // HybridAuth Module $hybridauth_config = include($_SERVER['DOCUMENT_ROOT'] . '/api/auth/config.php'); if ($_GET['provider'] == '' || !in_array($_GET['provider'], array_keys($hybridauth_config['providers']))) { echo 'Invalid Provider'; } else { try { $hybridauth = new Hybrid_Auth($hybridauth_config); // try to authenticate with this provider $adapter = $hybridauth->authenticate($_GET['provider']); // grab user profile if ($hybridauth->isConnectedWith($f_provider)) { // yep, we're connected. Add this provider's info to the user_auth table echo 'connection successful'; } } catch (Exception $e) { echo $e->getMessage(); } }
Он работает в том, что он пересылает Facebook и предлагает установить правильное приложение с соответствующими разрешениями. Это говорит о том, что моя конфигурация HA работает нормально. Я устанавливаю приложение успешно и затем перенаправляет обратно на страницу, откуда я получаю сообщение:
Authentification failed! Facebook returned an invalide user id.
Что дает? Мое приложение показывает 0 добавлений и 0 вызовов API в панели управления FB тоже (хотя эти данные выглядят так, как будто это может быть отложено на несколько дней). Я жду, когда FB включит приложение в некотором роде? Я делаю что-то неправильно?
ОБНОВИТЬ
HybridAuth использует SDK для Facebook, поэтому я попытался просто исключить HA из всего уравнения. Выполнение следующего базового примера:
session_start(); require($_SERVER['DOCUMENT_ROOT'] . "/path/to/fbsdk/facebook.php"); $facebook = new Facebook(array( 'appId' => 'myappid', 'secret' => 'myappsecret', 'fileUpload' => true )); $user = $facebook->getUser(); var_dump($user);
Я зарегистрировался в facebook, и у меня добавлено приложение, но независимо от того, что я делаю, идентификатор пользователя возвращает 0. Я тоже пытался использовать тестовых пользователей – безрезультатно. Есть ли проблема с конфигурацией сервера, которую я могу здесь пропустить?
Я переместил свой код на другое приложение / сервер, а затем в одно и то же приложение на другом сервере, и все сработало нормально. Поэтому я начал изучать его как проблему конфигурации сервера. Оказывается, Facebook не понравился самозаверяющий сертификат на моем сервере разработки.
Я смог решить эту проблему, изменив класс base_facebook.php в SDK PHP и добавив curlopt, чтобы игнорировать шаг проверки SSL. Смотри ниже:
public static $CURL_OPTS = array( CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 60, CURLOPT_USERAGENT => 'facebook-php-3.1', CURLOPT_SSL_VERIFYPEER => false );
Мне удалось выяснить, почему эта ошибка появляется даже в текущей версии hybridauth и facebook sdk.
Причина в том, как hyperautht и google или facebook sdk строят параметр redirect_uri. Как известно из https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/, сначала мы должны перенаправить пользователя в facebook (с параметром redirect_uri), и он возвращает код в ответ по умолчанию. Затем мы отправили http-запрос с использованием curl снова (с параметром redirect_uri), и эти URL-адреса не совпадают по причине, упомянутой ранее.
Другие слова, если вы установили в hybridauth config "base_url" => "http://
yourhost
/hybridauth/hybridauth" (без косой черты) -> он отлично работает для google, но даст вам эту глупую ошибку сообщения для входа в facebook.
"base_url" => "http://
yourhost
/hybridauth/hybridauth/" (с косой чертой) будет работать нормально с facebook, но приведет к ошибке с google с явной ошибкой «Redirect Uri missmatch».
Поэтому не лучшим решением для быстрого исправления является "base_url" => "http://
yourhost
/hybridauth/hybridauth » (без косой черты) в config.
И затем выберите, как построить uri, зависит от поставщика.
в строке комментария Provider_Adapter.php 131 // $this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.done={$this->id}";
// $this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.done={$this->id}";
и вместо этого добавьте эти два.
$dlm = $this->id == "Facebook" ? "/?" : "?";
$ this-> params ["login_done"] = $ HYBRID_AUTH_URL_BASE. (strpos ($ HYBRID_AUTH_URL_BASE, $ dlm)? '&': $ dlm). "Hauth.done = {$ this-> ID}";
Таким образом, у нас есть решение поддержать как Facebook, так и Google.
Для всех, кто подходит по этому поводу, и ответ выше не работает, я столкнулся с той же проблемой, и оказалось, что мое приложение в Facebook все еще находится в режиме Sandbox. Выключение этого параметра в настройках приложения оказалось для решения проблемы с получением идентификатора пользователя 0.
Hybrid auth добавляет серию параметров «0» в параметре scope. Я не уверен, насколько хороша эта идея изменения класса Hybrid auth core, но я только что изменил функцию loginBegin в Hybrid / Providers / Facebook.php и теперь работает нормально:
function loginBegin() { $parameters = array("scope" => $this->scope, "redirect_uri" => $this->endpoint, "display" => "page"); $optionals = array("scope", "redirect_uri", "display"); foreach ($optionals as $parameter){ if( isset( $this->config[$parameter] ) && ! empty( $this->config[$parameter] ) ){ $parameters[$parameter] = $this->config[$parameter]; } } if (isset($parameters['scope'])) { foreach ($parameters['scope'] as $key => $parameter){ if ($parameter == '0') { $parameters['scope'][$key] = ''; } } } // get the login url $url = $this->api->getLoginUrl( $parameters ); // redirect to facebook Hybrid_Auth::redirect( $url ); }