Php 登录系统无法登录
我的问题是,当我尝试登录时,我的脚本直接跳入循环的其他部分。 我尝试输入printf语句进行调试,并发现我的密码哈希与数据库中的值结合在一起Php 登录系统无法登录,php,mysql,login,Php,Mysql,Login,我的问题是,当我尝试登录时,我的脚本直接跳入循环的其他部分。 我尝试输入printf语句进行调试,并发现我的密码哈希与数据库中的值结合在一起 <?php //include_once './bin/configDb.php'; //MySQL connection variables $dbhost = 'localhost'; $dbname = 'ideabank'; $dbuser = 'xxx'; $dbpass = 'xxx'; $table = 'members'; // Co
<?php
//include_once './bin/configDb.php';
//MySQL connection variables
$dbhost = 'localhost';
$dbname = 'ideabank';
$dbuser = 'xxx';
$dbpass = 'xxx';
$table = 'members';
// Connect to server and select databse.
//include_once './bin/connectDb.php';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db($dbname, $conn);
// username and password sent from form, cleanout, esacpe string against sqlinj.
$username = mysql_real_escape_string($_POST['username']);
$password = hash('sha512', $_POST['password']);
printf("$username \n");
printf("$password \n");
$sql = "SELECT * FROM $table WHERE username = '$username' AND password = '$password'
";
$result=mysql_query($sql);
//$result = mysql_query("SELECT * FROM $table WHERE username = '$username' AND password = '$password'
//");
// Replace counting function based on database you are using.
$count=mysql_num_rows($result);
// If result matched $username and $password, table row must be 1 row
if($count==1){
// Register $username, $password and redirect to file "login_success.php"
session_register("username");
session_register("password");
header("location:login_success.php");
}
else {
echo "Wrong Username or Password";
}
exit ()
?>
然后我添加了这个以获取更多错误消息
var_dump($count);
还尝试了我的查询字符串
$sql = "SELECT * FROM $table WHERE username = '$username'";
这给了我这个值
$sqlint(0)
所以我的查询没有返回任何内容
因此,我更改了sql查询,将$table变量删除为确切的表名“members”
这给了我一个新的错误:
$sql Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in
/var/www/ideabank/checklogin.php on line 35 Call Stack: 0.0002 657184 1. {main}() /var/www/ideabank/checklogin.php:0 0.0006 660584 2. mysql_num_rows() /var/www/ideabank /checklogin.php:35 NULL
第35行是我的if($count==1)
因此,我针对数据库测试了一个简单的查询
SELECT * From members
结果是,显示第0-5行(共6行,查询耗时0.0004秒)
好的,我再次更改了查询
$sql = "SELECT * FROM members WHERE password = '$password'";
结果:
$sqlint(2)
这是正确的,因为我有两个相同密码的帐户
所以我又问了一个问题
$sql = "SELECT * FROM members WHERE username = '$username'";
这是有意义的,因为用户名是唯一的
结果:
$sql警告:mysql_num_rows()希望参数1是第35行调用堆栈上的/var/www/ideabank/checklogin.php中给定的资源布尔值:0.0002 653256 1。{main}()/var/www/ideabank/checklogin.php:0.0007 656528 2。mysql_num_rows()/var/www/ideabank/checklogin.php:35 NULL
当警告发出时,第35行出现错误,返回NULL
创建警告的行是我的计数器,它用于确保只显示一条记录
我最初的想法是
若结果匹配$username和$password,则行必须==到1
但它抛出相同的sql错误
现在我尝试更改计数器并使用mysql_num_行
if (
mysql_num_rows($result))
{
session_start();
...
eller
if (
mysql_num_rows($result) == 1)
{
session_start();
...
但是它仍然会抛出sql警告。a)session_register()已被弃用,应该不惜一切代价避免使用。改用$\u会话['varname']=$varvalue
。另外,请确保您实际完成了会话\u start()
b) 您得到的数据库错误表明您的查询字符串有错误。代码中没有任何错误处理,因此将所有数据库查询调用更改为:
$result = mysql_query($sql) or die($sql . "<br>" . mysql_error());
$result=mysql\u query($sql)或die($sql。“
”.mysql\u error());
这将在错误发生时中止脚本,向您显示查询字符串以及确切的错误是什么。尝试:
$result=mysql\u query($sql,$conn)代码>(进行查询时,需要指定要使用的连接)
当SELECT语句的调用成功时,它将返回一个资源,当它失败时,它将返回false(一个布尔值-正是mysql\u num\u rows
所抱怨的)。在请求行信息之前,您应该确保mysql\u查询
部分成功
具体地说,让我们添加一些错误捕获代码(仅用于开发目的,不用于生产-没有人希望在使用站点时看到die
语句-对于生产,应该显示一条漂亮且可能不太具描述性的消息):
发布变量:
你应该检查你的POST
变量!您可能没有获得发布的用户名
密码
变量。。。第二个问题不会立即引起注意,因为散列算法会将空白字符串转换为静止字符串
print_r($_POST); //Make sure you see username/password here
或者更好:
if ($_POST['username']=="") {
//Report username is required
} elseif ($_POST["password"]=="") {
//Report password is required
}
您也可以考虑<代码> $$请求< /代码>超全局,它也允许$yGET变量(test .php?用户名=Me&密码=1234),有时$KOKII{取决于<代码> php.ini > /Calp>设置}
样式更改
你说:
这是正确的,因为我有两个相同密码的帐户
您可能需要考虑唯一的加盐过程,这样任何两个拥有相同密码的用户在DB中都不会有相同的散列值。最简单的方法是使用用户名(已经是一个方便的唯一值),您可以先对其进行一次散列(尽管这是否有好处还存在争议)。就目前情况而言,可能会对您的数据库使用攻击
<?php
//include_once './bin/configDb.php';
//MySQL connection variables
$dbhost = 'localhost';
$dbname = 'ideabank';
$dbuser = 'xxx';
$dbpass = 'xxx';
$table = 'members';
// Connect to server and select databse.
//include_once './bin/connectDb.php';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db($dbname, $conn);
// username and password sent from form, cleanout, esacpe string against sqlinj.
$username = mysql_real_escape_string($_POST['username']);
$password = hash('sha512', $_POST['password']);
printf("$username \n");
printf("$password \n");
$sql = "SELECT * FROM $table WHERE username = '$username' AND password = '$password'
";
$result=mysql_query($sql);
//$result = mysql_query("SELECT * FROM $table WHERE username = '$username' AND password = '$password'
//");
// Replace counting function based on database you are using.
$count=mysql_num_rows($result);
// If result matched $username and $password, table row must be 1 row
if($count==1){
// Register $username, $password and redirect to file "login_success.php"
session_register("username");
session_register("password");
header("location:login_success.php");
}
else {
echo "Wrong Username or Password";
}
exit ()
?>
第二种风格是关于如何检查用户名/密码。我会使用SQL提取用户的记录(如果他们不是用户,则无记录),然后使用PHP比较密码,因此脚本为:
$username=mysql_real_escape_string($_POST['username']);
//First lookup the user
$sql="SELECT username,password FROM members WHERE username='$username'";
if (!$result=mysql_query($sql,$conn)) {
echo "Username or password is invalid.";
exit();
//In truth username not found - for testing you could be
// more specific, or perhaps log the event internally:
}
$user=mysql_fetch_assoc($result);
//Assumes only one user can ever match, well more accurately will only
// access the first user ever found. (Reasonable since your user-create
// process would filter duplicate usernames, or perhaps a members.UNIQUEKEY
//Following will only work if you change the way passwords are stored
define("SITESALT","NaCL"); //Should likely be defined in a header library
// (since other pages like account-creation will require it)
if ($user["password"]!=
hash('sha512',$user["username"].SITESALT.$_POST["password"])) {
echo "Username or password is invalid.";
exit();
//In truth password is incorrect - might want to log.
}
/* //Alternate based on your existing pwd storage
if ($user["password"]!=hash('sha512',$_POST["password"])) {
echo "Username or password is invalid.";
exit();
}*/
header("location:login_succes.php");
上面提到的一个方便的好处是,如果您添加了其他应该在登录时验证的用户属性(例如enabled=1、expires>=now()等),这些属性应该向用户提供更具体的消息(例如“您的帐户已过期”),那么基础工作已经就绪。首先检查mysql\u query()的返回值。
阅读SQL注入漏洞以及如何在PHP中防止这些漏洞。您的代码是一个等待发生的安全噩梦。首先通过mysql\u real\u escape\u string()
运行用户名和密码。或者更好地使用它,它会为您提供占位符
不要使用session\u register()
因为您正在使用sha512
,您应该将密码
字段的类型更改为varchar(512)
,否则在写入数据库时密码将被截断为256个字符。确定,所以你首先要解决的是一个明显的问题,我已经解决了。我的查询字符串现在有一个指定的连接要使用。其次,我在连接部分添加了错误处理,它不返回任何错误。为了进一步检查,我在密码中输入了一个typ0,它确实返回了一个错误。所以我认为我与mysql的连接还可以。然后我在查询部分添加了如下错误处理:$result=mysql\u query($sql,$conn)或die($sql。“
”.mysql\u error())作为Marc Surpsts。@Johan Nielsen-和?成功?我同意你的看法。稍后我将添加反sqlinj属性,例如escape\u string。但就目前而言,理顺基本面将是一件好事:)我现在添加了a)和b)我仍然被重新引导到我来自的地方。那将是我的另一部分哈哈哈,真是
<?php
//include_once './bin/configDb.php';
//MySQL connection variables
$dbhost = 'localhost';
$dbname = 'ideabank';
$dbuser = 'xxx';
$dbpass = 'xxx';
$table = 'members';
// Connect to server and select databse.
//include_once './bin/connectDb.php';
$conn = mysql_connect($dbhost, $dbuser, $dbpass);
mysql_select_db($dbname, $conn);
// username and password sent from form, cleanout, esacpe string against sqlinj.
$username = mysql_real_escape_string($_POST['username']);
$password = hash('sha512', $_POST['password']);
printf("$username \n");
printf("$password \n");
$sql = "SELECT * FROM $table WHERE username = '$username' AND password = '$password'
";
$result=mysql_query($sql);
//$result = mysql_query("SELECT * FROM $table WHERE username = '$username' AND password = '$password'
//");
// Replace counting function based on database you are using.
$count=mysql_num_rows($result);
// If result matched $username and $password, table row must be 1 row
if($count==1){
// Register $username, $password and redirect to file "login_success.php"
session_register("username");
session_register("password");
header("location:login_success.php");
}
else {
echo "Wrong Username or Password";
}
exit ()
?>
if( mysql_query($query) ) {
// retrieve result
}
else {
die( mysql_error() );
}