又是一个简单但不太明显的问题。这次是在PHP中登录和会话。
就我对它的安全方面的理解:
-
发送到MySQL前检查所有变量
-
使用$_POST隐藏信息
-
记录会话
嗯,我有一些代码'学习/制作',但如果你能指出的东西,我错过了一点解释,我将非常感激,也可能是许多像我这样的初学者有用的。(我读过很多关于它的问题,但大多数时候答案都是这样开始的——尽管代码在很多方面都是灾难性的,具体的答案是…)
这里有:
index . php
<html>
<head>
<title>Website</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<ul><li><a href="index.php">HOME</a></li><li><a href="menu1.php">menu1</a></li><li><a href="logout.php">logout</a></li></ul>
</body>
</html>
session.php:
<?php
session_start();
if (!isset($_SESSION["txtUserId"])) {
require "login.php";
exit;
}
login。
require_once('db_connect.php');
$errorMessage = '';
if (isset($_POST['txtUserId']) && isset($_POST['txtPassword'])) {
// check if the user id and password combination is correct
$random = '$%hgy5djk3tgbG^bhk';;
$logname=htmlspecialchars($_POST['txtUserId']);
$pass=sha1(($_POST['txtPassword']).$random)
$sql = "SELECT user, pass FROM users WHERE username= :login";
$stmt = $db->prepare($sql);
$stmt->bindvalue( ':login', $logname);
$stmt->execute();
if $stmt['pass']==$pass {
// set the session
$_SESSION['basic_is_logged_in'] = true;
header('Location: main.php');
exit;
}
else {
$errorMessage = 'Sorry, wrong user id / password';
require "login.php";
}
}
?>
<html>
<head>
<title>Login ...</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body>
<?php
if ($errorMessage != '') {
?>
<p align="center"><strong><font color="#990000"><?php echo $errorMessage; ?></font></strong></p>
<?php
}
?>
<form method="post" name="frmLogin" id="frmLogin">
<table width="400" border="1" align="center" cellpadding="2" cellspacing="2">
<tr>
<td width="150">User Id</td>
<td><input name="txtUserId" type="text" id="txtUserId"></td>
</tr>
<tr>
<td width="150">Password</td>
<td><input name="txtPassword" type="password" id="txtPassword"></td>
</tr>
<tr>
<td width="150"> </td>
<td><input type="submit" name="btnLogin" value="Login"></td>
</tr>
</table>
</form>
</body>
</html>
db_connect.php:
<?php
$hostname = "localhost";
$username = "name";
$password = "pass";
try {
$pdo = new PDO("mysql:host=$hostname; dbname=dbnamehere", $username, $password);
//echo "Connected to database"; // check for connection
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
对于初学者来说,如果出现登录错误,您的代码将运行一个无限的中断循环。你需要一个文件从其内部,这是行不通的。我很佩服你花时间去正确理解一些安全基础知识,并在你的DB调用中实现了PDO,并使用prepare语句正确地转义了用户输入。
编辑
我假设您的登录页面实际上存在于index.php。与login.php脚本中的"回显"语句相反,我将允许整个脚本处理,捕获已知$_SESSION变量中的任何错误,例如:
$ _SESSION [' login_valid_error '] = "文本" .
在脚本末尾,
if(isset($_SESSION['login_valid_error']) && !empty($_SESSION['login_valid_error'])) {
header(...) //take the person to logged in page
} else {
header('Location: index.php');
}
然后回到index.php,在表单的上方创建一个错误通知部分(使用一些css),如果页面被加载并且变量存在,则回显它:
<?php
if(isset($_SESSION['login_valid_error'])) {
echo '<div class="error">'. $_SESSION['login_valid_error'] .'</div>';
unset($_SESSION['login_valid_error']);
}
?>
确保在页面加载后取消该变量的设置(任何对页面的新尝试都会收集新的错误)。
我也会考虑使用像phpass链接在这里。乍一看可能有点难以理解,但请下载代码并查看示例。它实际上非常容易集成,并且可以让您跳过对密码等用户输入进行盐化/散列处理的担忧。
$_POST变量只对用户隐藏数据,但它除了模糊之外没有增加任何安全性。
安全考虑应该包括(至少)表单中唯一的令牌(所有表单!)以防止跨站点脚本,验证令牌,加密对登录表单的请求(至少),加密和盐(唯一的,未存储的盐)您的用户密码,以及验证和消毒所有用户输入的数据。
我建议使用支持良好的MVC框架,它将为您处理大部分安全性。
这里有一些视频,你正在尝试做什么,使用CodeIgniter MVC框架:
- http://heybigname.com/2011/07/28/codeigniter-2-sparks-php-activerecord-part-1-installation/
- http://heybigname.com/2011/08/03/codeigniter-2-sparks-php-activerecord-part-2-the-user-model/
- http://heybigname.com/2011/08/17/codeigniter-2-sparks-php-activerecord-part-3-login/
和Hello World和Blog的例子:
- http://codeigniter.com/tutorials/