用于BaseFacebook类的GAE上的卷曲替换

时间:2014-01-07 09:30:52

标签: php facebook google-app-engine curl oauth-2.0

我想在 PHP 中对我的GAE应用实施联合登录。

我看过像janrain或OAuth plugin这样的第三方,但我不能轻易地整合它们,我不想付钱或限制。我只想要一些简单的东西,它将挂钩到GAE认证模型中。

目前我有google和yahoo,因为他们是唯一一个使用不需要用户名的端点,我可以使用UserService::createLoginUrl()

我想添加Facebook,Twitter和微软,以及其他我想的,但这些是我现在的目标。

我开始使用facebook我正在尝试使用facebook连接器。最初我开始使用Javascript API并且它运行良好,直到你坐在防火墙后面并且facebook被阻止(然后$.getScript()无法管理失败),所以我开始查看PHP库(至少阻塞是一个)对用户可见,b)不是我对陷阱和处理的责任,c)非常适合我的URL端点模型)

问题是BaseFacebook类使用cURL。 GAE没有。

有没有人知道如何将身份验证构建到GAE中,以便我可以使用login: required,如果没有,任何拥有比我更好的流/卷曲知识的人都可以替换BaseFacebook类中的cURL内容。这是导致我悲伤的功能:

/**
 * Makes an HTTP request. This method can be overridden by subclasses if
 * developers want to do fancier things or use something other than curl to
 * make the request.
 *
 * @param string $url The URL to make the request to
 * @param array $params The parameters to use for the POST body
 * @param CurlHandler $ch Initialized curl handle
 *
 * @return string The response text
 */
protected function makeRequest($url, $params, $ch=null) {
    if (!$ch) {
        $ch = curl_init();
    }

    $opts = self::$CURL_OPTS;
    if ($this->getFileUploadSupport()) {
        $opts[CURLOPT_POSTFIELDS] = $params;
    } else {
        $opts[CURLOPT_POSTFIELDS] = http_build_query($params, null, '&');
    }
    $opts[CURLOPT_URL] = $url;

    // disable the 'Expect: 100-continue' behaviour. This causes CURL to wait
    // for 2 seconds if the server does not support this header.
    if (isset($opts[CURLOPT_HTTPHEADER])) {
        $existing_headers = $opts[CURLOPT_HTTPHEADER];
        $existing_headers[] = 'Expect:';
        $opts[CURLOPT_HTTPHEADER] = $existing_headers;
    } else {
        $opts[CURLOPT_HTTPHEADER] = array('Expect:');
    }

    curl_setopt_array($ch, $opts);
    $result = curl_exec($ch);

    $errno = curl_errno($ch);
    // CURLE_SSL_CACERT || CURLE_SSL_CACERT_BADFILE
    if ($errno == 60 || $errno == 77) {
        self::errorLog('Invalid or no certificate authority found, '.
                'using bundled information');
        curl_setopt($ch, CURLOPT_CAINFO,
        dirname(__FILE__) . DIRECTORY_SEPARATOR . 'fb_ca_chain_bundle.crt');
        $result = curl_exec($ch);
    }

    // With dual stacked DNS responses, it's possible for a server to
    // have IPv6 enabled but not have IPv6 connectivity.  If this is
    // the case, curl will try IPv4 first and if that fails, then it will
    // fall back to IPv6 and the error EHOSTUNREACH is returned by the
    // operating system.
    if ($result === false && empty($opts[CURLOPT_IPRESOLVE])) {
        $matches = array();
        $regex = '/Failed to connect to ([^:].*): Network is unreachable/';
        if (preg_match($regex, curl_error($ch), $matches)) {
            if (strlen(@inet_pton($matches[1])) === 16) {
                self::errorLog('Invalid IPv6 configuration on server, '.
                        'Please disable or get native IPv6 on your server.');
                self::$CURL_OPTS[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4;
                curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
                $result = curl_exec($ch);
            }
        }
    }

    if ($result === false) {
        $e = new FacebookApiException(array(
                'error_code' => curl_errno($ch),
                'error' => array(
                        'message' => curl_error($ch),
                        'type' => 'CurlException',
                ),
        ));
        curl_close($ch);
        throw $e;
    }
    curl_close($ch);
    return $result;
}

1 个答案:

答案 0 :(得分:0)

Google App Engine中的

login: required无法通过您的应用程序进行扩展。如果您希望提供多个提供商的登录信息,您需要在app.yaml中关闭该信息,然后在您的应用程序中处理身份验证 - 这听起来就像您正在处理的那样。

您可能希望查看使用Google Identity Toolkit - 它为您列出的某些提供商(不仅仅是Google)提供登录信息,并提供PHP示例: https://developers.google.com/identity-toolkit/