php基于表单密码验证与HTTP验证用法实例
本文实例讲述了php基于表单密码验证与HTTP验证用法。分享给大家供大家参考。具体分析如下:
PHP的HTTP认证机制仅在PHP以Apache模块方式运行时才有效,因此该功能不适用于CGI版本。在Apache模块的PHP脚本中,可以用header()函数来向客户端浏览器发送“AuthenticationRequired”信息,使其弹出一个用户名/密码输入窗口。当用户输入用户名和密码后,包含有URL的PHP脚本将会加上预定义变量PHP_AUTH_USER,PHP_AUTH_PW和AUTH_TYPE被再次调用,这三个变量分别被设定为用户名,密码和认证类型。预定义变量保存在$_SERVER或者$HTTP_SERVER_VARS数组中。支持“Basic”和“Digest”(自PHP5.1.0起)认证方法。感兴趣的朋友可以参阅header()函数相关信息。
PHP版本问题:Autoglobals全局变量,包括$_SERVER等,自PHP4.1.0起有效,$HTTP_SERVER_VARS从PHP3开始有效。
以下是在页面上强迫客户端认证的脚本范例.
例子34-1.BasicHTTP认证范例
if(!isset($_SERVER["PHP_AUTH_USER"])){
header("WWW-Authenticate:Basicrealm="MyRealm"");
header("HTTP/1.0401Unauthorized");
echo"TexttosendifuserhitsCancelbutton";
exit;
}else{
echo"<p>Hello{$_SERVER["PHP_AUTH_USER"]}.</p>";
echo"<p>Youentered{$_SERVER["PHP_AUTH_PW"]}asyourpassword.</p>";
}
?>
例子34-2.DigestHTTP认证范例
本例演示怎样实现一个简单的DigestHTTP认证脚本,更多信息请参考RFC2617.
$realm="Restrictedarea";
//user=>password
$users=array("admin"=>"mypass","guest"=>"guest");
if(!isset($_SERVER["PHP_AUTH_DIGEST"])){
header("HTTP/1.1401Unauthorized");
header("WWW-Authenticate:Digestrealm="".$realm.
""qop="auth"nonce="".uniqid().""opaque="".md5($realm).""");
die("TexttosendifuserhitsCancelbutton");
}
//analizethePHP_AUTH_DIGESTvariable
preg_match("/username="(?P<username>.*)",s*realm="(?P<realm>.*)",s*nonce="(?P<nonce>.*)",s*uri="(?P<uri>.*)",s*response="(?P<response>.*)",s*opaque="(?P<opaque>.*)",s*qop=(?P<qop>.*),s*nc=(?P<nc>.*),s*cnonce="(?P<cnonce>.*)"/",$_SERVER["PHP_AUTH_DIGEST"],$digest);
if(!isset($users[$digest["username"]]))
die("Usernamenotvalid!");
//generatethevalidresponse
$A1=md5($digest["username"].":".$realm.":".$users[$digest["username"]]);
$A2=md5($_SERVER["REQUEST_METHOD"].":".$digest["uri"]);
$valid_response=md5($A1.":".$digest["nonce"].":".$digest["nc"].":".$digest["cnonce"].":".$digest["qop"].":".$A2);
if($digest["response"]!=$valid_response)
die("WrongCredentials!");
//ok,validusername&password
echo"Yourareloggedinas:".$digest["username"];
?>
兼容性问题:在编写HTTP标头代码时请格外小心,为了对所有的客户端保证兼容性,关键字“Basic”的第一个字母必须大写为“B”,分界字符串必须用双引号(不是单引号)引用;并且在标头行HTTP/1.0401中,在401前必须有且仅有一个空格.
在以上例子中,仅仅只打印出了PHP_AUTH_USER和PHP_AUTH_PW的值,但在实际运用中,可能需要对用户名和密码的合法性进行检查,或许进行数据库教程的查询,或许从dbm文件中检索.
注意有些InternetExplorer浏览器本身有问题。它对标头的顺序显得似乎有点吹毛求疵。目前看来在发送HTTP/1.0401之前先发送WWW-Authenticate标头似乎可以解决此问题。
自PHP4.3.0起,为了防止有人通过编写脚本来从用传统外部机制认证的页面上获取密码,当外部认证对特定页面有效,并且安全模式被开启时,PHP_AUTH变量将不会被设置,但无论如何,REMOTE_USER可以被用来辨认外部认证的用户,因此可以用$_SERVER["REMOTE_USER"]变量.
配置说明:PHP用是否有AuthType指令来判断外部认证机制是否有效。
注意,这仍然不能防止有人通过未认证的URL来从同一服务器上认证的URL上偷取密码.
NetscapeNavigator和InternetExplorer浏览器都会在收到401的服务端返回信息时清空所有的本地浏览器整个域的Windows认证缓存,这能够有效的注销一个用户,并迫使他们重新输入他们的用户名和密码,有些人用这种方法来使登录状态“过期”,或者作为“注销”按钮的响应行为.
例子34-3.强迫重新输入用户名和密码的HTTP认证的范例
functionauthenticate(){
header("WWW-Authenticate:Basicrealm="TestAuthenticationSystem"");
header("HTTP/1.0401Unauthorized");
echo"YoumustenteravalidloginIDandpasswordtoaccessthisresourcen";
exit;
}
if(!isset($_SERVER["PHP_AUTH_USER"])||
($_POST["SeenBefore"]==1&&$_POST["OldAuth"]==$_SERVER["PHP_AUTH_USER"])){
authenticate();
}
else{
echo"<p>Welcome:{$_SERVER["PHP_AUTH_USER"]}<br/>";
echo"Old:{$_REQUEST["OldAuth"]}";
echo"<formaction="{$_SERVER["PHP_SELF"]}"METHOD="post">n";
echo"<inputtype="hidden"name="SeenBefore"value="1"/>n";
echo"<inputtype="hidden"name="OldAuth"value="{$_SERVER["PHP_AUTH_USER"]}"/>n";
echo"<inputtype="submit"value="ReAuthenticate"/>n";
echo"</form></p>n";
}
?>
该行为对于HTTP的Basic认证标准来说并不是必须的,因此不能依靠这种方法,对Lynx浏览器的测试表明Lynx在收到401的服务端返回信息时不会清空认证文件,因此只要对认证文件的检查要求没有变化,只要用户点击“后退”按钮,再点击“前进”按钮,其原有资源仍然能够被访问,不过,用户可以通过按“_”键来清空他们的认证信息.
在下例中,我们是使用$PHP_AUTH_USER和$PHP_AUTH_PW这两个变量来验证进入者是否合法并允许进入。在本例中被允许登录的用户名称和密码对分别为tnc和nature:
if(!isset($PHP_AUTH_USER))
{
Header("WWW-Authenticate:Basicrealm="MyRealm"");
Header("HTTP/1.0401Unauthorized");
echo"TexttosendifuserhitsCancelbuttonn";
exit;
}
else
{
if(!($PHP_AUTH_USER=="tnc"&&$PHP_AUTH_PW=="nature"))
{
//如果是错误的用户名称/密码对,强制再验证
Header("WWW-Authenticate:Basicrealm="MyRealm"");
Header("HTTP/1.0401Unauthorized");
echo"ERROR:$PHP_AUTH_USER/$PHP_AUTH_PWisinvalid.";
exit;
}
else
{
echo"Welcometnc!";
}
?>
事实上再实际引用中不大可能如上面使用代码段明显的用户名称/密码对,而是利用数据库或者加密的密码文件存取它们.
根据指定的验证信息核实用户身份:
首先,我们可以使用以下代码确定用户是否已经输入了用户名和密码,并显示出用户输入的信息.
if(!isset($PHP_AUTH_USER)){
header("WWW-Authenticate:Basicrealm="MyPrivateStuff"");
header("HTTP/1.0401Unauthorized");
echo"AuthorizationRequired.";
exit;
}
else{
echo"<P>Youhaveenteredthisusername:$PHP_AUTH_USER<br>
Youhaveenteredthispassword:$PHP_AUTH_PW<br>
Theauthorizationtypeis:$PHP_AUTH_TYPE</p>";
}
?>
说明:
isset()函数用于确定某个变量是否已被赋值,根据变量值是否存在,返回true或false.
header()函数用于发送特定的HTTP标头,注意,使用header()函数时,一定要在任何产生实际输出的HTML或PHP代码前面调用该函数.
虽然上述代码相当简单,没有根据任何实际值对用户输入的用户名和密码进行有效验证,但是至少我们了解了如何使用PHP在客户端产生输入对话框.
下面,我们就来了解一下如何根据指定的验证信息核实用户身份,代码如下:
if(!isset($PHP_AUTH_USER)){
header("WWW-Authenticate:Basicrealm="MyPrivateStuff"");
header("HTTP/1.0401Unauthorized");
echo"AuthorizationRequired.";
exit;
}
elseif(isset($PHP_AUTH_USER)){
if(($PHP_AUTH_USER!="admin")||($PHP_AUTH_PW!="123")){
header("WWW-Authenticate:Basicrealm="MyPrivateStuff"");
header("HTTP/1.0401Unauthorized");
echo"AuthorizationRequired.";
exit;
}else{
echo"<P>You"reauthorized!</p>";
}
}
?>
在这里,我们首先检查用户是否已经输入了用户名称和密码,如果没有则弹出相应对话框要求用户输入身份信息,随后,我们通过判断用户输入的信息是否符合admin/123这一指定用户帐号来授予用户访问权限或提示用户再次输入正确的信息,这种方法适用于所有用户都使用同一登录帐号的网站.
另一种简易的密码验证
如果你是在windows98下面编写和运行着你的PHP脚本,或者是你在Linux下面按默认设置,将PHP安装成一个CGI程序的话,你将无法使用上面的PHP程序来实现验证功能,为此,无边给大家提供了另外一种简易的密码验证的方法,虽然实用性不大,但是拿来学习还是挺好的.
if($_POST[Submit]=="提交"){ //如果用户提交了数据,则执行操作
$password=$_POST[password]; //获取用户输入的数据,并保存在变量password中
$cpassword=$_POST[cpassword]; //获取用户输入的确认数据,保存在变量$cpassord中
if(emptyempty($password)||emptyempty($cpassword))
{
die("密码不可空!");
}
elseif(((strlen($password)<5)||(strlen($password)>15)))
{
die("密码长度在5和15之间");
}
//---值比较
elseif(!(strlen($password)==strlen($cpassword)))
{
die("两次输入密码不匹配!");
}
elseif(!($password===$cpassword))//值和数据类型比较
{
die("两次密码不匹配!");
}
else //循环输出密码,因为是密码所以输出*号
{
for($i=0;$i<strlen($password);$i++)
{
echo"*";
}
}
}
?>
<html>
<head>
<metahttp-equiv="Content-Type"content="text/html;charset=gb2312">
<title>表单验证-密码字段验证</title>
</head>
<body>
<formname="form1"method="post"action="<?=$_SERVER["PHP_SELF"]?>">
请输入密码:<inputtype="text"name="password"><br>
确认密码:<inputtype="password"name="cpassword"><br>
<inputtype="submit"name="Submit"value="提交">
</form>
</body>
</html>
希望本文所述对大家的php程序设计有所帮助。
相关文章
- python 类属性和实例属性、类方法, 静态方法, 实例方法、接口, 协议和抽象基类 (4.2)
- JavaScript验证字符串只能包含数字或者英文字符的代码实例详解编程语言
- 数据库PHP究竟如何还原MySQL数据库?(php还原mysql)
- 展现魅力:PHP支持MySQL扩展(php支持mysql扩展)
- PHP实现将数组插入MySQL数据库(php数组插入mysql)
- 测试MySQL触发器构建:PHP测试实例(mysql触发器php)
- PHP助力MySQL实现程序开发梦想(php支持mysql)
- 探寻Linux下PHP路径之旅(linux查看php路径)
- Linux下运行PHP脚本的简单步骤(linux运行php脚本)
- 安装Linux环境的PHP扩展指南(linux安装php扩展)
- 数据库解决PHP无法连接MySQL数据库的问题.(php无法连接mysql)
- 分钟结合简单快捷:PHP跟MySQL搭配,5分钟搞定!(php与mysql5)
- 数据库使用PHP框架管理Oracle数据库(php框架oracle)
- PHP 如何调用 MySQL 函数(php调用mysql函数)
- 使用PHP操作Redis实例:简单高效的数据存储方案(php操作redis实例)
- 快速了解Oracle创建表实例操作指南(oracle创建表实例)
- 使用PHP实现Redis快速构建应用(redis实例php)
- 使用PHP实现Redis分布式缓存(php实例化redis)
- 如何使用PHP重启Linux服务:简易教程(php重启linux服务)
- PHP与MySQL完美结合:数据库操作常用语句及优化技巧(php使用mysql)
- 使用PHP 驱动MSSQL支撑稳固的开发环境(php mssql 驱动)
- 用PHP实现Redis缓存一个实例(redis缓存实例php)
- PHP和Mysqlweb应用开发核心技术第1部分Php基础-1开始了解php
- php二维数组用键名分组相加实例函数
- python单链表实现代码实例
- java获取当前日期使用实例
- php根据身份证号码计算年龄的实例代码
- android实现简单的画画板实例代码
- JAVA算法起步之插入排序实例
- php定时计划任务与fsockopen持续进程实例
- php验证用户名是否以字母开头与验证密码实例
- php下Memcached入门实例解析
- PHP中$this和$that指针使用实例