使用 HTTP-Basic 身份验证发出 HTTP GET 请求

Posted

技术标签:

【中文标题】使用 HTTP-Basic 身份验证发出 HTTP GET 请求【英文标题】:Making a HTTP GET request with HTTP-Basic authentication 【发布时间】:2011-12-05 16:00:41 【问题描述】:

我需要为我正在处理的 Flash Player 项目构建代理。我只需要通过 HTTP 基本身份验证向另一个 URL 发出 HTTP GET 请求,并提供来自 php 的响应,就好像 PHP 文件是原始源一样。我该怎么做?

【问题讨论】:

你需要一个全 PHP 的解决方案还是允许你对 curl 进行外部调用? 如果curl 很容易获得,我可能会使用它。我希望我的脚本在尽可能多的机器上尽可能“正常工作”。 curl 不是现成的,但您当然需要为每个目标平台操作系统重新编译源代码。我看到使用 curl 的主要优点是:1)支持“开箱即用”的复杂内容(例如带有身份验证的 HTTP 代理和客户端证书),以及 2)诊断(帮助您找出某些 HTTP 事务失败的原因)。 【参考方案1】:

Marc B 很好地回答了这个问题。我最近采用了他的方法并想分享生成的代码。

<?PHP

$username = "some-username";
$password = "some-password";
$remote_url = 'http://www.somedomain.com/path/to/file';

// Create a stream
$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header' => "Authorization: Basic " . base64_encode("$username:$password")                 
  )
);

$context = stream_context_create($opts);

// Open the file using the HTTP headers set above
$file = file_get_contents($remote_url, false, $context);

print($file);

?>

希望对大家有所帮助!

【讨论】:

不,他在回答问题时做得很差。你做得很好。 (投票数同意我的看法!)【参考方案2】:

使用file_get_contents()stream 来指定HTTP 凭据,或者使用curlCURLOPT_USERPWD 选项。

【讨论】:

+1 - 另请注意,如果您没有流支持 (PHP4) 或 cURL 扩展不可用,您可以使用 http://user:pass@domain.tld/file URL 语法和 file_get_contents(),它将提供 HTTP基本的身份验证功能。 @DaveRandom 更好,太棒了。 你能举一个PHP的例子来说明如何做到这一点,我有点卡住了,我尝试了几种不同的方法都没有成功。 您能更具体地说明您尝试过的内容吗? The manpage for file_get_contents() 有一些示例没有 HTTP 基本身份验证 - 那些 适合您吗?如果是这样,并且由于某种原因添加 auth 前缀失败,那么您可能会从 print_r(error_get_last()) 获得提示。 @DaveRandom 将凭据放在 URL 中的解决方案效果很好,除非发生从 http 到 https 的重定向。在这种情况下,PHP 会“释放”对 https URL 的请求的凭据。但如果它们在上下文中,它们仍然会被使用。【参考方案3】:

我把@clone45 的代码变成了一系列函数 像 Python 的 requests 仅使用不使用外部代码的接口(足以满足我的目的)。也许它可以帮助别人。

它处理:

基本认证 标题 获取参数

用法:

$url = 'http://sweet-api.com/api';
$params = array('skip' => 0, 'top' => 5000);
$header = array('Content-Type' => 'application/json');
$header = addBasicAuth($header, getenv('USER'), getenv('PASS'));
$response = request("GET", $url, $header, $params);
print($response);

定义

function addBasicAuth($header, $username, $password) 
    $header['Authorization'] = 'Basic '.base64_encode("$username:$password");
    return $header;


// method should be "GET", "PUT", etc..
function request($method, $url, $header, $params) 
    $opts = array(
        'http' => array(
            'method' => $method,
        ),
    );

    // serialize the header if needed
    if (!empty($header)) 
        $header_str = '';
        foreach ($header as $key => $value) 
            $header_str .= "$key: $value\r\n";
        
        $header_str .= "\r\n";
        $opts['http']['header'] = $header_str;
    

    // serialize the params if there are any
    if (!empty($params)) 
        $params_array = array();
        foreach ($params as $key => $value) 
            $params_array[] = "$key=$value";
        
        $url .= '?'.implode('&', $params_array);
    

    $context = stream_context_create($opts);
    $data = file_get_contents($url, false, $context);
    return $data;

【讨论】:

太好了,谢谢。如果响应带有链接怎么办?当点击响应页面上的链接时,如何使用链接 url 调用请求函数? @Sadik 如果响应来自链接,您需要从获得的字符串中解析它们。例如,如果是 JSON,则可以使用 json_decode 函数。【参考方案4】:

你真的想用 php 来做这个吗?

一个简单的 javascript 脚本就可以做到:

function login(username, password, url) 

  var http = getHTTPObject();

  http.open("get", url, false, username, password);
  http.send("");
  //alert ("HTTP status : "+http.status);

  if (http.status == 200) 
    //alert ("New window will be open");
    window.open(url, "My access", "width=200,height=200", "width=300,height=400,scrollbars=yes");
    //win.document.location = url;
   else 
    alert("No access to the secured web site");
  



function getHTTPObject()  

  var xmlhttp = false;
  if (typeof XMLHttpRequest != 'undefined') 
    try 
      xmlhttp = new XMLHttpRequest();
     catch (e) 
      xmlhttp = false;
    
   else 
    /*@cc_on
    @if (@_jscript_version >= 5)
    try 
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
     catch (e) 
      try 
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
       catch (E) 
        xmlhttp = false;
      
    
    @end @*/
  
  return xmlhttp;

【讨论】:

处理旨在跨站点共享的内容,因此没有外部 JavaScript 将起作用,不幸的是,需要托管的全 PHP 解决方案。

以上是关于使用 HTTP-Basic 身份验证发出 HTTP GET 请求的主要内容,如果未能解决你的问题,请参考以下文章

在 java 中使用 http 标头在 Spring Security 中传递基本身份验证详细信息

使用 Javascript 发出 HTTP POST 身份验证基本请求

Firestore REST API 使用 http-client 发出经过身份验证的请求

如何在 Swift 中发出 HTTP 请求 + 基本身份验证

使用 HTTP Web 请求发送 HTTP 标头以进行 NTLM 身份验证

经过身份验证的 http 请求 swift Alamofire