HybridAuth / PHP Facebook SDK authentication failed (getUser returns 0)

我们两清 提交于 2019-12-01 13:28:12

I moved my code to a different app/server and then to the same app on a different server and everything worked fine. So I started looking into it as a server configuration issue. Turns out Facebook didn't like the self-signed certificate on my development server.

I was able to solve this problem by altering the base_facebook.php class in the PHP SDK and adding the curlopt to ignore the SSL verification step. See below:

  public static $CURL_OPTS = array(
    CURLOPT_CONNECTTIMEOUT => 10,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT        => 60,
    CURLOPT_USERAGENT      => 'facebook-php-3.1',
    CURLOPT_SSL_VERIFYPEER => false
  );

I've managed to figure out why this error appears even in current version of hybridauth and facebook sdk.

The reason is in the way how hybridauth and google or facebook sdk builds redirect_uri parameter. As We know from https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/ first we have to redirect user to facebook ( with redirect_uri param ) and it returns code in response by default. Than we sent http request using curl again ( with redirect_uri param ) and these urls doesn't match, because of the reason mentioned before.

Other words if you set in hybridauth config "base_url" => "http://yourhost/hybridauth/hybridauth" ( without slash ) -> it will work fine for google, but give you this stupid message error for facebook login.

"base_url" => "http://yourhost/hybridauth/hybridauth/", ( with slash ) will work ok with facebook but will result error with google with clear error "Redirect Uri missmatch".

So not the best by quick fix is "base_url" => "http://yourhost/hybridauth/hybridauth" ( without slash ) in config.

And then choose how to build uri depends on provider.

in Provider_Adapter.php comment line 131 // $this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, '?' ) ? '&' : '?' ) . "hauth.done={$this->id}";

and add these two instead.

$dlm = $this->id == "Facebook" ? "/?" : "?";

$this->params["login_done"] = $HYBRID_AUTH_URL_BASE . ( strpos( $HYBRID_AUTH_URL_BASE, $dlm ) ? '&' : $dlm ) . "hauth.done={$this->id}";

Such way we have solution to support both Facebook and Google.

For anyone else coming accross this and the answer above doesn't work, I was facing the same issue an turns out my app on Facebook was still in Sandbox mode. Turning this off under the app settings turned out to solve the issue of getting a 0 user id.

Hybrid auth adds a series of "0"s in scope parameter. I am not sure how good is this idea of modifying the Hybrid auth core class but I just modified the loginBegin function in Hybrid/Providers/Facebook.php and it is working fine now:

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 );
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!