如何在 PHP 中使用基本 HTTP 身份验证?
Posted
技术标签:
【中文标题】如何在 PHP 中使用基本 HTTP 身份验证?【英文标题】:How can I use Basic HTTP Authentication in PHP? 【发布时间】:2011-05-08 05:19:54 【问题描述】:我正在尝试使用 Basic HTTP Authentication 并按照 php 手册页上的示例进行操作。但这对我不起作用。变量$_SERVER['PHP_AUTH_USER']
似乎没有设置。当用户尝试登录时,系统会提示用户使用新的登录对话框。服务器正在运行 PHP 5.3.3,我已经尝试使用 Google Chrome 和 Internet Explorer。
这是我使用的简单示例:
<?php
if (!isset($_SERVER['PHP_AUTH_USER']))
header('WWW-Authenticate: Basic realm="Jonas Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'User pressed Cancel';
exit;
else
echo "<p>Hello $_SERVER['PHP_AUTH_USER'].</p>";
echo "<p>You entered $_SERVER['PHP_AUTH_PW'] as you password.</p>";
?>
怎么了?
【问题讨论】:
与其尝试用 PHP 做这件事,不如使用 Web 服务器,例如httpd.apache.org/docs/2.2/howto/auth.html @James:我认为我的虚拟主机使用 Apache。 @Phil:那么我的 PHP 代码将依赖于我的 Web 服务器,并且我无法轻松更改为另一个 Web 服务器。我想遵循 HTTP 标准。 Unauthorized 首先是拼写错误。您的示例比您引用的链接短。 您是否阅读了您关注的链接上的 cmets?有针对不同 Web 服务器和程序的多个版本的建议,其中之一可能更适合您的需求。对于 PHP,我发现手册 cmets 比手册中的描述更有用。 【参考方案1】:试试这个::
<?php
/*
** Define a couple of functions for
** starting and ending an HTML document
*/
function startPage()
print("<html>\n");
print("<head>\n");
print("<title>Listing 24-1</title>\n");
print("</head>\n");
print("<body>\n");
function endPage()
print("</body>\n");
print("</html>\n");
/*
** test for username/password
*/
if( ( isset($_SERVER['PHP_AUTH_USER'] ) && ( $_SERVER['PHP_AUTH_USER'] == "leon" ) ) AND
( isset($_SERVER['PHP_AUTH_PW'] ) && ( $_SERVER['PHP_AUTH_PW'] == "secret" )) )
startPage();
print("You have logged in successfully!<br>\n");
endPage();
else
//Send headers to cause a browser to request
//username and password from user
header("WWW-Authenticate: " .
"Basic realm=\"Leon's Protected Area\"");
header("HTTP/1.0 401 Unauthorized");
//Show failure text, which browsers usually
//show only after several failed attempts
print("This page is protected by HTTP " .
"Authentication.<br>\nUse <b>leon</b> " .
"for the username, and <b>secret</b> " .
"for the password.<br>\n");
?>
【讨论】:
【参考方案2】:对于 PHP-CGI:
在 .htaccess 中添加:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule .* - [E=HTTP_AUTHORIZATION:%HTTP:Authorization,L]
</IfModule>
并在脚本的开头添加以下内容:
list($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW']) = explode(':' , base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));
【讨论】:
substr()
很可疑。我将首先在第一个空格处断开字符串并确保身份验证类型确实设置为Basic
(忽略大小写)。然后得到第二部分并解码。
如何实现自动登录?我已经添加了上面的代码,但我有点困惑在我的应用程序中从哪里开始【参考方案3】:
PHP 是如何运行的?如果是通过 Apache mod_cgi,恐怕你根本拿不到认证信息。除非您使用 SECURITY_HOLE_PASS_AUTHORIZATION
标志编译它,否则 Apache 不会将它传递给 CGI 应用程序。 (这是否真的是一个安全漏洞取决于您服务器上的其他用户是否具有比您的网站用户更低或更高的权限。)
如果是 IIS CGI,您必须确保仅配置了“匿名”目录访问,否则 IIS 将尝试介入并自行验证凭据。
echo "<p>Hello $_SERVER['PHP_AUTH_USER'].</p>";
HTML 注入安全漏洞(好吧,如果有效的话)。使用htmlspecialchars()
。伙计,那个 PHP 文档页面是否充满了高度可疑的建议和代码。
您也可以尝试查看$_SERVER['HTTP_AUTHORIZATION']
,尽管我怀疑这是 mod_cgi 问题,在这种情况下两个变量都不会出现,您将不得不求助于基于 cookie 的登录。或者更改为使用更现代的 PHP 托管方法的主机,例如 FastCGI 或 mod_php。
【讨论】:
【参考方案4】:我认为 PHP 方法依赖于在 Web 服务器上配置的基本身份验证。一个简单的方法是在您要为其启用基本身份验证的目录中包含一个 .htaccess 文件。
大多数基于 unix 的网络主机都允许您通过上传此文件来执行此操作。一个单独的文件(称为 .htauth)将保存允许访问该站点或目录的用户登录信息。
【讨论】:
这是不正确的。 PHP 可以完全控制发送给客户端(浏览器)的 headers。 @phil 不正确。 Apache 总是发送一个“Server:”标头,而 PHP 无法阻止它。【参考方案5】:检查您是否在尝试访问这两个变量的位置之前覆盖了变量$_SERVER[‘PHP_AUTH_USER’]
和$_SERVER[‘PHP_AUTH_PW’]
。
如果不是上述情况,请检查您是否使用 php 作为 cgi mod。如果您使用 php 作为 cgi mod,那么在大多数情况下,您不会得到 $_SERVER[‘PHP_AUTH_USER’]
和$_SERVER[‘PHP_AUTH_PW’]
,因为我们通常不会使用选项 SECURITY_HOLE_PASS_AUTHORIZATION
编译 apache
因此,如果您想同时获取这两个变量,请使用选项 SECURITY_HOLE_PASS_AUTHORIZATION 重新编译 apache,或者您可以使用 .htaccess 方法。
【讨论】:
以上是关于如何在 PHP 中使用基本 HTTP 身份验证?的主要内容,如果未能解决你的问题,请参考以下文章
使用 HTTP 基本身份验证获取 JWT 令牌的安全性如何?
PHP cURL - 具有基本身份验证的HTTP GET 403