首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >登录系统无法登录

登录系统无法登录
EN

Stack Overflow用户
提问于 2011-07-29 01:07:44
回答 4查看 651关注 0票数 1

我的问题是,当我尝试登录时,我的脚本直接跳到循环的else部分。我尝试放入printf语句进行调试,并发现我的密码散列与数据库中的值一致。

代码语言:javascript
复制
<?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 ()
?>

我的MYSQL数据库是这样的:

代码语言:javascript
复制
CREATE TABLE IF NOT EXISTS `members` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`password` varchar(256) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

然后我添加了这个,以获得更多的错误消息

代码语言:javascript
复制
var_dump($count);

我还尝试使用我的查询字符串

代码语言:javascript
复制
$sql = "SELECT * FROM $table WHERE username = '$username'";

这给了我这样的价值

$sqlint(0)

因此,我的查询不会返回任何内容。

因此,我通过将$table变量删除为确切的表名"members“来更改sql查询。

它给了我一个新的错误:

代码语言:javascript
复制
$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)

因此,我对数据库测试了一个简单的查询

代码语言:javascript
复制
    SELECT * From members

结果是,显示了第0.0004 -5行(总共6行,查询耗时0.0004秒)

好的,所以我再次更改了查询

代码语言:javascript
复制
$sql = "SELECT * FROM members WHERE password = '$password'";

结果:

$sqlint(2)

这是正确的,因为我有两个帐户使用相同的密码。

所以我做了另一个查询

代码语言:javascript
复制
$sql = "SELECT * FROM members WHERE username = '$username'";

这是有意义的,因为用户名是唯一的

结果:

$sql警告: mysql_num_rows()要求参数1为资源,布尔值位于/var/www/ideabank/checklogin.php第35行调用堆栈: 0.0002 653256 1. {main}() /var/www/ideabank/checklogin.php:0 0.0007 0.0007 2. mysql_num_rows() /var/www/ideabank/checklogin.php:35 NULL

当警告执行时,第35行有一个错误,返回NULL!

创建警告的行是my counter,它的存在是为了确保只显示一条记录。

我最初的想法是,

如果结果与$username & $password匹配,则行必须为==到1

但是它抛出了相同的sql错误

现在,我尝试更改计数器,改为使用mysql_num_rows

代码语言:javascript
复制
if (
mysql_num_rows($result))
{
session_start();
...
eller
if (
mysql_num_rows($result) == 1)
{
session_start();
...

但它仍然会抛出sql警告。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-07-29 01:34:46

由于您使用的是sha512,因此应该将password字段的类型更改为varchar(512),否则在写入数据库时,您的密码将被截断为256个字符。

票数 0
EN

Stack Overflow用户

发布于 2011-07-29 01:13:22

Try:$result=mysql_query($sql,$conn); (在进行查询时,需要指定要使用的连接)。

当SELECT语句的mysql_query成功时,它将返回一个资源,当它失败时,它将返回false (一个布尔值--这正是mysql_num_rows所抱怨的)。在请求行信息之前,您应该确保mysql_query部件成功。

具体地说,让我们添加一些错误捕获代码(仅用于开发,不用于生产-使用站点时,没有人希望看到die语句-对于生产,应该显示一条很好的消息,但描述性可能要小得多):

代码语言:javascript
复制
if (!$conn = mysql_connect($dbhost, $dbuser, $dbpass)) {
   //This is a horrible idea in production but shows you the failure 
   // while you're coding
   die ("Failed to connect to DB.");
}
if (!mysql_select_db($dbname, $conn)) {
   //Still a bad idea!
   die ("Unable to select DB $dbname");
}

/* ... */

if (!$result=mysql_query($sql,$conn)) {
   //Still bad!
   die ("Unable to execute $sql");
}

POST变量:

你应该检查你的POST变量!您可能无法获得发布的username password变量...第二个不会立即引起注意,因为散列算法会将一个空白字符串转换为其他字符串。

代码语言:javascript
复制
print_r($_POST); //Make sure you see username/password here

或者更好:

代码语言:javascript
复制
if ($_POST['username']=="") {
  //Report username is required
} elseif ($_POST["password"]=="") {
  //Report password is required
}

您还可以考虑$_REQUEST超级全局,它还将允许$_GET变量(test.php?username=me&password=1234),有时还允许$_COOKIE {取决于php.ini设置}

样式更改

你可以说:

,这是正确的,因为我有两个帐户使用相同的密码。

您可能需要考虑对散列过程进行唯一加盐处理,这样具有相同密码的任何两个用户在数据库中都不会具有相同的散列值。要做到这一点,最简单的方法是使用用户名(已经是一个方便的唯一值),您可以先对其进行一次散列(尽管这是否提供了好处尚有争议)。因为它是站立的,所以可以在您的数据库上使用rainbow table攻击。

第二个风格是关于如何检查用户名/密码。我将使用SQL来提取用户的记录(如果他们不是用户,则为none ),然后使用PHP来比较密码,因此脚本将为:

代码语言:javascript
复制
$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()等),它们应该为用户提供更具体的消息(例如,“您的帐号已过期”)基础工作已经完成。

票数 1
EN

Stack Overflow用户

发布于 2011-07-29 01:16:56

首先检查mysql_query()的返回值

代码语言:javascript
复制
if( mysql_query($query) ) {
     // retrieve result
}
else {
    die( mysql_error() );
}

阅读有关SQL注入漏洞以及如何在PHP中预防它们的文章。你的代码是一个等待发生的安全噩梦。首先,通过mysql_real_escape_string()运行用户名和密码。或者更好的做法是使用PDO,它为您提供了占位符。

不要使用session_register()

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6862851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档