HTTP基本验证(WWW-Authenticate)
public function indexAction(){
$this->requireAuth();
}
public function forceAuth(){
//PHP Protected Area 这个是弹框中显示的内容
header('WWW-Authenticate: Basic realm="PHP Protected Area"');
header('HTTP/1.0 401 Unauthorized');
die('验证被取消');
}
public function requireAuth(){
if ( isset($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']) ){
$username = $_SERVER['PHP_AUTH_USER'];
$pwd = $_SERVER['PHP_AUTH_PW'];
}
//简单的判断
if (isset($username) && $username!='zyk'){
//验证不通过
$this->forceAuth();
}else{
echo "<p>你的用户名{$username}</p>";
echo "<p>你的密码{$pwd}</p>";
echo base64_decode('YToxMjM');
}
}
请求该方法页面会出现一个要求授权的弹框
输入对应的信息之后在请求头里会有
Authorization Basic YToxMjM=
其中YToxMjM= 是base64(username:password)
这个可以做一个很简单的验证
摘要访问验证
public function indexAction()
{
$this->requireAuth();
}
private function forceAuth($realm,$nonce){
// $nonce:服务端的随机数据
header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.$nonce.'",opaque="'.md5($realm).'"');
header('HTTP/1.0 401 Unauthorized');
die('验证被取消');
}
private function requireAuth(){
$realm = 'check';
//生成随机数
$nonce = uniqid();
$digest = $this->getDigest();
if ($digest==''){
$this->forceAuth($realm, $nonce);
}
$digestParts = $this->digestParse($digest);
//var_dump($digestParts);
$validUser = 'admin1';
$validPass = '123';
//$validUser用户名 $realm:保护领域名称
$A1 = md5("{$validUser}:{$realm}:{$validPass}");
$A2 = md5("{$_SERVER['REQUEST_METHOD']}:{$digestParts['uri']}");
//cnonce:客户端的随机数据,使用qop指令才会有 qop:客户端选定的保护方法 nc:客户端重复使用nonce时的使用次数
$validResponse = md5("{$A1}:{$digestParts['nonce']}:{$digestParts['nc']}:{$digestParts['cnonce']}:{$digestParts['qop']}:{$A2}");
if ($digestParts['response']!=$validResponse){
$this->forceAuth($realm, $nonce);
}
echo '登录成功';
}
private function getDigest(){
if (isset($_SERVER['PHP_AUTH_DIGEST'])){
//username="admin", realm="check", nonce="5b98dd65f1a92", uri="/test/index", response="3499757ece7ffbe82f24fb5efb30b90a", opaque="0ba4439ee9a46d9d9f14c60f88f45f87", qop=auth, nc=00000005, cnonce="da76265c17be484a"
return $_SERVER['PHP_AUTH_DIGEST'];
}elseif (isset($_SERVER['HTTP_AUTHENTICATION']) && strpos(strtolower($_SERVER['HTTP_AUTHENTICATION']), 'digest')===0){
return substr($_SERVER['HTTP_AUTHENTICATION'], 7);
}
return '';
}
/**
* 提取签名信息
* @param unknown $digest */
private function digestParse($digest){
//要校验的参数,防止数据丢失
$need_parts = [
'nonce'=>1,
'nc'=>1,
'cnonce'=>1,
'qop'=>1,
'username'=>1,
'uri'=>1,
'response'=>1,
];
//$digest类似 username="admin", realm="check", nonce="5b98dd65f1a92",uri="/test/index", response="3499757ece7ffbe82f24fb5efb30b90a",opaque="0ba4439ee9a46d9d9f14c60f88f45f87", qop=auth, nc=00000005, cnonce="da76265c17be484a"
//\w:由数字、26个英文字母或者下划线组成的字符串 ?:表示这个括号里的分组不会被引用/捕获 \s任意一个空白字符(空格、换行符、换页符、回车符、字表符)
//书上方式1:preg_match_all('/(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))*/', $digest,$matches,PREG_SET_ORDER);
//自己写的方法
preg_match_all('/(\w+)="?([^",]+)["|,],?/',$digest,$matches,PREG_SET_ORDER);
foreach ($matches as $m){
$data[$m['1']] = $m['2']?$m['2']:$m['3'];
//将匹配到的参数删除
unset($need_parts[$m['1']]);
}
//为空说明,参数都有匹配到
return empty($need_parts)?$data:false;
}
出现下面的弹框说明成功一般
输入你设定的,进行登录
$validUser = ‘admin1’;
$validPass = ‘123’;