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
状态码攻击利用。这里不多说,懂的都懂。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。