php登录表单 - 安全基础知识

时间:2011-09-22 21:35:35

标签: php mysql login

再一个简单但不是很明显的问题来自我。这次是在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.php     

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();
    }
?>

2 个答案:

答案 0 :(得分:2)

对于初学者,如果发生登录错误,您的代码将运行无限且破坏的循环。您需要一个内部无法使用的文件。令我印象深刻的是,您花了很多时间来正确理解一些安全基础知识,并在您的数据库调用中实现了PDO并使用prepare语句正确地转移了用户输入。

修改

我假设你的登录页面实际上存在于index.php上。与login.php脚本中的'echoing'语句相反,我将允许整个脚本处理,捕获已知$ _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 link is here之类的东西。一开始看起来有点压倒性但是下载代码并查看示例。它实际上非常容易集成,并且可以让您省去对密码等用户输入进行盐析/哈希处理的担忧。

答案 1 :(得分:1)

$ _POST变量仅隐藏来自用户的数据,但它不会添加除默默无闻之外的任何安全性。

安全注意事项应该包括(至少)表单中的唯一令牌(所有表单!),以防止跨站点脚本,验证令牌,加密对登录表单的请求(至少),加密和腌制(唯一,未存储的盐)您的用户密码,以及验证和清理所有用户输入的数据。

我建议使用支持良好的MVC框架,它将为您处理大部分安全性。

使用CodeIgniter MVC框架,以下是您正在尝试做的一些视频:

以及Hello World和Blog示例: