PHP登录表单-安全基础


php login form - security basics

又是一个简单但不太明显的问题。这次是在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">&nbsp;</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/