原文作者:Deian Motov
发布日期:Sunday, 30 September 2007
译 者:石头希迁
表单(Form)和函数
这是另一个例子,稍微复杂了一点点:
在这个例子中,输入的表单的值被保存到一个叫做email的cookie中,在接下来的访问中请求中,这个cookie可以自动填写表单,在需要用户输入用户名和密码的时候,这个技术被很多网站频繁使用。帮助用户在登录界面自动填写上次成功登录的用户名,这样也帮助用户少敲几次键盘。
<?php
if (!isset($_POST['email'])) {
// if form has not been submitted
// display form
// if cookie already exists, pre-fill form field with cookie value
?>
<html>
<head></head>
<body>
<form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
Enter your email address: <input type="text" name="email" value="<?php echo $_COOKIE['email']; ?>">
<input type="submit" name="submit">
<?php
// also calculate the time since the last submission
if ($_COOKIE['lastsave']) {
$days = round((time() - $_COOKIE['lastsave']) / 86400);
echo "$days day(s) since last submission";
}
?>
</form>
</body>
</html>
<?php
}
else {
// if form has been submitted
// set cookies with form value and timestamp
// both cookies expire after 30 days
if (!empty($_POST['email'])) {
setcookie("email", $_POST['email'], mktime()+(86400*30), "/");
setcookie("lastsave", time(), mktime()+(86400*30), "/");
echo "Your email address has been recorded.";
}
else {
echo "ERROR: Please enter your email address!";
}
}
?>
</body>
</html>
这个例子也演示了如何对一个域使用多个cookie,这需要调用setcookie多次。在上面的例子中,登录的时间被保存为第二个cookie,用来计算两次登录间的时间间隔。
要从客户端删除一个cookie,可以以同样的语法调用setcookie() ,而将过期时间设定为一个已经过去的时间,这将导致客户端自动删除cookie。下面是例子:
如果需要知道更多关于cookie和setcookie()函数,可以参阅链接
<?php
// delete cookie
setcookie("lastsave", NULL, mktime() - 3600, "/");
?>
http://www.php.net/manual/en/features.cookies.php和
http://www.php.net/manual/en/function.setcookie.php.
访问授权
如我在教程的最开始说的,cookie和sessions是两种使得数据“长久”存于客户端的方法。一个session保持一次会话的时的数据,而cookie可以保存任何你需要它保存的时间。记住这些,让我们继续看看如何同时使用它们两者。
这个应用是一个简单的用户授权系统。这个系统中,一些页面只能显示给成功登录的用户,任何没有提供有效密码的用户都无法看到那些“特殊”的页面。用户和用户密码被保存在一个MySQL数据库表中。PHP使用这个表来进行有效的用户认证,以确定用户是否有权访问。
假设用户的MySQL数据表看起如下:
每一个用户有一个用户名和一个有SHA1()函数处理后的密码,下面是使用PHP来做这个艰巨工作的相关代码:
+-------+---------------------------------------------------+
| name | pass |
+-------+---------------------------------------------------+
| sue | 9565d44fd0fe4db59f073eea1db70f3ea258e10b |
| harry | 6e74234b8b552685113b53c7bff0f386c8cef8cf |
| louis | 6817dda51b64b8190029490d2811a4d9cb9cd432 |
| sam | bd17f8243e771a57cfbb06aa9a82bbf09fd2d90b |
| james | 792ec9b44d432c947ac6775b2b52326e9d08512f |
+-------+---------------------------------------------------+
<?php这里,在登录框输入的值将会被集成进入MySQL SELECT查询语句,对用户表执行相关查询。如果用户名和密码都符合,会返回单一的一行数据,表示授权成功,如果不是,即没有获得任何数据,则授权失败。(译注:这个脚本存在被SQL注入攻击的可能性,请不要直接使用)
if (isset($_POST['name']) || isset($_POST['pass'])) {
// form submitted
// check for required values
if (empty($_POST['name'])) {
die ("ERROR: Please enter username!");
}
if (empty($_POST['pass'])) {
die ("ERROR: Please enter password!");
}
// set server access variables
$host = "localhost";
$user = "test";
$pass = "test";
$db = "db2";
// open connection
$connection = mysql_connect($host, $user, $pass) or die ("Unable to connect!");
// select database
mysql_select_db($db) or die ("Unable to select database!");
// create query
$query = "SELECT * FROM users WHERE name = '" . $_POST['name'] . "' AND pass = SHA1('" . $_POST['pass'] . "')";
// execute query
$result = mysql_query($query) or die ("Error in query: $query. " . mysql_error());
// see if any rows were returned
if (mysql_num_rows($result) == 1) {
// if a row was returned
// authentication was successful
// create session and set cookie with username
session_start();
$_SESSION['auth'] = 1;
setcookie("username", $_POST['name'], time()+(84600*30));
echo "Access granted!";
}
else {
// no result
// authentication failed
echo "ERROR: Incorrect username or password!";
}
// free result set memory
mysql_free_result($result);
// close connection
mysql_close($connection);
}
else {
// no submission
// display login form
?>
<html>
<head></head>
<body>
<center>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
Username <input type="text" name="name" value="<?php echo $_COOKIE['username']; ?>">
<p />
Password <input type="password" name="pass">
<p />
<input type="submit" name="submit" value="Log In">
</center>
</body>
</html>
<?php
}
?>
假设授权成功了,就会初始化一次会话,$_SESSION['auth'] 将会创建,并被赋值为Boolean值True。用户名将会被保存到一个cookie中,以备下次之需。cookie会被保存30天,会被用来在下次登录时自动填写登录框的用户名。
当然,仅仅上面这些还不够。上面的脚本执行了用户的授权,初始化了session,设置了cookie,但是,在每次访问有限制的页面时也要进行安全检查。没有此安全检查,用户可以通过直接输入相关URL来绕过登录界面。
因为上面脚本中session变量$_SESSION['auth'] 只在用户认证完成了以后才有效,因此可以在每个限制页面脚本的前面先检查此变量是否存在。下面是代码:
这是一个安全页面,只在$_SESSION['auth'] = 1的情况下,才可以显示。
<?php
// start session
session_start();
if (!$_SESSION['auth'] == 1) {
// check if authentication was performed
// else die with error
die ("ERROR: Unauthorized access!");
}
else {
?>
<html>
<head></head>
<body>
This is a secure page. You can only see this if $_SESSION['auth'] = 1
</body>
</html>
<?php
}
?>
相当的简洁,对吧?只有授权用户才可以看到这个页面,因为只有他们的客户端才会拥有一个 $_SESSION['auth'] 变量有效的会话。其他用户只能看到一个error消息。
(--The End--)
没有评论:
发表评论