php如何处理401状态码,完成Basic realm授权认证闭环?
发布于 作者:苏南大叔 来源:程序如此灵动~
401状态码是一个非常神奇的状态码,可以通过客户端出现的一个登陆用户名和密码,来完成一套realm登陆体系的认证。本文从php的代码层面上来分析一下这个realm认证协议的过程。

苏南大叔的“程序如此灵动”博客,记录苏南大叔的编程经验总结。本文测试环境:win10,nginx@1.15.11,php@8.2.9nts,chrome@121.0.6167.140。
写在前面
不仅是php,nginx也可以发出和处理401状态码的realm认证。可以参考:
然而,这个401状态码的认证,需要浏览器来完成对应的登录框的弹出。并不是所有的浏览器都会弹出登录框[大多数会正确弹出],不同的浏览器弹出的框框也不是统一的样式。比如:electron作为一种变种的浏览器,是需要做特殊编程处理,才能够处理401状态的。参考文章:
本文是以最新的chrome浏览器为客户端的,可以正确处理401请求,以完成业务闭环。
发出需要认证请求
header('WWW-Authenticate: Basic realm="My Realm Name"');
header('HTTP/1.0 401 Unauthorized');
接收用户名密码
所有需要的信息,都存在于$_SERVER变量中,有:
- 提交的用户名:
$_SERVER['PHP_AUTH_USER'] - 提交的密 码:
$_SERVER['PHP_AUTH_PW'] - 一个未知变量:
$_SERVER["HTTP_AUTHORIZATION"]

完整代码
$username = @trim($_SERVER['PHP_AUTH_USER']);
$password = @trim($_SERVER['PHP_AUTH_PW']);
if ($username == "admin" && $password == "password") {
echo "<p>欢迎您,{$_SERVER['PHP_AUTH_USER']}</p>";
var_dump($_SERVER["HTTP_AUTHORIZATION"]);
} else {
auth();
// if ($username == "" || $password == "") {
// echo "用户名密码不能为空";
// } else {
// echo "用户名密码错误";
// }
}
function auth() {
header('WWW-Authenticate: Basic realm="My Realm Name"');
header('HTTP/1.0 401 Unauthorized');
echo '点击取消按钮之后显示这句话';
}思考一,realm名称
客户端和服务端进行交互,除了传统的get和post之类的网页可控的内容外,还有个被遗忘的角落,就是这个header交互。本文中,服务器端在发送传统的网页内容的同时,在最顶部发送了一个401状态码。401状态码被浏览器正确处理后,就会在页面渲染前弹出个样式不统一的登录框。
关于"My Realm Name"字样,在古老的浏览器上,它是会被显示出来的。但是,近年的浏览器并不显示这些字样了。
思考二,鉴权加密解密
从原理上来说,客户端实际上发送了一个header头,名叫Authorization。在php那边,从所有headers里面,得到的就是HTTP_AUTHORIZATION。
它的内容以开头,表明协议方式是realm。后面的YWRtaW46cGFzc3dvcmQ=就是个base64编码了。它解码之后的内容是“admin:password”,就是客户在登录框里面输入的内容。所以,如果使用代码去模拟这个过程的话,该怎么操作,大家都明白了吧?
思考三,变量获取方式
数据是通过header从客户端传递的,$_SERVERS是将经过php加工过的。header是每次提交的结果展示,$_SERVERS是经过不断整理汇总的结果。虽然两者数据有重叠,但是还是有区别的。
| 变量 | 值 |
|---|---|
| getallheaders()["Authorization"] | Basic YWRtaW46cGFzc3dvcmQ= |
| $_SERVER["HTTP_AUTHORIZATION"] | Basic YWRtaW46cGFzc3dvcmQ= |
参考文章:
总结
实际效果上来看,这个realm方式,毕竟登录框逻辑是由浏览器所控制的。所以,相比较传统的表单登陆方式,它就显得不够灵活方便。
另外,401状态码是个非常有故事的状态码,如果一个网站可以任意调用其它网站的资源(比如图片)。那么,理论上来说,这个网站就可以被401状态码攻击利用。这里不多说,懂的都懂。