【问题标题】:file_get_contents('php://input') keeps returning emptyfile_get_contents('php://input') 一直返回空
【发布时间】:2012-08-09 21:27:06
【问题描述】:

我正在尝试在我的网站中设置 gitkit,但无法通过这一行代码。不管我做什么,file_get_contents 总是返回空。

我已经设置了我的 php.ini :always_populate_raw_post_data = On

我的环境是PHP 5.3.3、Apache 2.2.6、localhost。

这是一些代码。

在我的 index.php 中,我调用 google API 并尝试使用 gmail 帐户登录,也就是联合登录。

(来自 Google API 控制台)

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.2/jquery-ui.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/googleapis/0.0.4/googleapis.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/jsapi"></script>
<script type="text/javascript">
  google.load("identitytoolkit", "1", {packages: ["ac"], language:"en"});
</script>
<script type="text/javascript">
  $(function() {
    window.google.identitytoolkit.setConfig({
        developerKey: "HERE_GOES_MY_DEVELOPER_KEY",
        companyName: "Valentinos Pizzaria",
        callbackUrl: "http://localhost/valentinos/callback.php",
        realm: "",
        userStatusUrl: "http://localhost/valentinos/userstatus.php",
        loginUrl: "http://localhost/valentinos/login.php",
        signupUrl: "http://localhost/valentinos/register.php",
        homeUrl: "http://localhost/valentinos/index.php",
        logoutUrl: "http://localhost/valentinos/logout.php",
        idps: ["Gmail", "Yahoo"],
        tryFederatedFirst: true,
        useCachedUserStatus: false,
        useContextParam: true
    });
    $("#navbar").accountChooser();
  });
</script>

我收到 IDP 响应、登录并被要求授予权限。返回到我的回调页面后,我在其中使用了 Google 提供的代码示例(如下所示),这一行代码似乎没有正确返回。

我是不是在做傻事?

我们将不胜感激。

到目前为止,这是整个 callback.php(目前还没有任何 HTML):

  session_start();

  $url = EasyRpService::getCurrentUrl();
  #$postData = @file_get_contents('php://input');
  $postData = file_get_contents('php://input');
  $result = EasyRpService::verify($url, $postData);
  // Turn on for debugging.
  // var_dump($result);

class EasyRpService {
  // Replace $YOUR_DEVELOPER_KEY
  private static $SERVER_URL = 'https://www.googleapis.com/rpc?key=HERE_GOES_MY_DEVELOPER_KEY';

  public static function getCurrentUrl() {
    $url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
    $url .= $_SERVER['SERVER_NAME'];
    if ($_SERVER['SERVER_PORT'] != '80') {
      $url .= ':'. $_SERVER['SERVER_PORT'];
    }
    $url .= $_SERVER['REQUEST_URI'];
    return $url;
  }

  private static function post($postData) {
    $ch = curl_init();
    curl_setopt_array($ch, array(
        CURLOPT_URL => EasyRpService::$SERVER_URL,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
        CURLOPT_POSTFIELDS => json_encode($postData)));
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    if ($http_code == '200' && !empty($response)) {
      return json_decode($response, true);
    }
    return NULL;
  }

  public static function verify($continueUri, $response) {
    $request = array();
    $request['method'] = 'identitytoolkit.relyingparty.verifyAssertion';
    $request['apiVersion'] = 'v1';
    $request['params'] = array();
    $request['params']['requestUri'] = $continueUri;
    $request['params']['postBody'] = $response;

    $result = EasyRpService::post($request);
    if (!empty($result['result'])) {
      return $result['result'];
    }
    return NULL;
  }

} # End Class EasyRpService

在有人问之前,我确实将 HERE_GOES_MY_DEVELOPER_KEY 替换为我的开发者密钥...

再次感谢任何帮助。 嗯。

【问题讨论】:

    标签: php file-get-contents


    【解决方案1】:

    您尝试过使用 $_POST 吗? php://input don't work 用于 enctype="multipart/form-data"。在这种情况下,您可能会收到 multipart/form-data 的响应 $_POST[0] 应该可以工作。

    【讨论】:

    • 是的,我从 $_REQUEST 中得到了结果,但它们使用 EasyRpService 类的方法 verify 评估为 null。如何检查 enctype 是否为 multipart/form-data?我相信 curl 正在将 http-header 设置为 application/json ...
    【解决方案2】:

    HTTP POST 数据通常填充在 $_POST 中,php://input 通常包含 PUT 数据。

    【讨论】:

    • Google Api 文档指出“身份提供者可以使用 POST 或 GET,并且您的应用程序需要能够同时处理这两种方式以支持所有用户”。 file_get_contents('php://input') 应该获取 API 提供的原始 json 返回。我可以使用 $_REQUEST 获取数据,但这对于 json 返回是不正确的,这让我陷入了 file_get_contents('php://input') 的困境。这不正确吗?
    • 考虑到 PHP 手册,我还想说你的回答有点不精确。 php.net/manual/en/wrappers.php.php "php://input 是一个只读流,允许您从请求正文中读取原始数据。对于 POST 请求,最好使用 php://input 而不是 $HTTP_RAW_POST_DATA .. 。”
    • 是的,$_POST 不是 HTTP_RAW_POST_DATA。正如 while1 所述,php://input 不适用于 enctype="multipart/form-data"。
    • 另外,如果 google 向您发送带有参数的 GET 请求,则 php://input 将不会被填充,您需要检查当前请求是 POST 还是 GET 请求并做出反应相应地。
    • 嗯,事实证明你是对的:他们从来没有给我发过帖子正文,只是一个获取请求,应该换成一个令牌。但我的问题在代码内部更深,因为 curl 正在返回 false。我必须添加一个选项,而不是验证 ssl 才能使其正常工作,我在这篇文章的评论中发现了这一点:stackoverflow.com/questions/5657382/… -> curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    猜你喜欢
    • 2015-01-24
    • 2013-10-09
    • 1970-01-01
    • 2016-06-02
    • 1970-01-01
    • 2016-12-27
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    相关资源
    最近更新 更多