ASP.NET注册页面:无法在sql数据库中插入数据

时间:2016-05-14 15:21:13

标签: c# mysql sql asp.net database

我正在开发一个需要注册页面的ASP.NET项目。以下代码验证用户名或电子邮件地址是否已存在,但如果一切正常,则不会将数据插入数据库。我做错了什么?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data.SqlClient;
using System.Configuration;
using System.Drawing;

namespace BootstrapRegisterLogin
{
    public partial class SignUp : System.Web.UI.Page
    {
        bool flag = false;

        protected void Page_Load(object sender, EventArgs e)
        {
        }

        private String EncryptPassword(string pass)
        {
            pass = tbPass.Text;
            byte[] bytes = System.Text.Encoding.Unicode.GetBytes(pass);
            string EncryptedPassword = Convert.ToBase64String(bytes);
            return EncryptedPassword;
        }   

        protected void btSignup_Click(object sender, EventArgs e)
        {
            if (tbName.Text != "" && tbEmail.Text != "" && tbUname.Text != "" && tbPass.Text != "" && tbCPass.Text != "" && tbHoneypot.Text == "")
            {
                if (tbPass.Text == tbCPass.Text)
                {
                    String CS = ConfigurationManager.ConnectionStrings["MyDatabaseConectionString1"].ConnectionString;
                    using (SqlConnection con = new SqlConnection(CS))
                    {
                        con.Open();

                        SqlCommand verifica = new SqlCommand();
                        verifica.CommandText = "select * from [Users]";
                        verifica.Connection = con;

                        SqlDataReader rd = verifica.ExecuteReader();
                        while (rd.Read())
                        {
                            if (rd[1].ToString() == tbUname.Text || rd[3].ToString() == tbEmail.Text)
                            {
                                flag = true;
                                break;
                            }
                        }

                        if (flag == true)
                        {
                            if (rd[1].ToString() == tbUname.Text)
                            {
                                lblMsg.Text = "Username already exists!";
                            }

                            if (rd[3].ToString() == tbEmail.Text)
                            {
                                lblMsg.Text = "Email already exists in the database!";
                            }
                        }
                        else
                        {
                            SqlCommand cmd = new SqlCommand("insert into Users values('" + tbUname.Text + "','" + EncryptPassword(tbPass.Text) + "','" + tbEmail.Text + "','" + tbName.Text + "','" + tbHoneypot.Text + "','U')", con);
                            //cmd.ExecuteNonQuery();
                            lblMsg.Text = "Congratulations! Registration complete!!";
                            lblMsg.ForeColor = Color.Green;
                            Response.Redirect("~/Login.aspx");
                        }
                    }
                }
                else
                {
                    lblMsg.Text = "The two passwords don't match!";
                }
            }
            else if (tbHoneypot.Text != "")
            {
                lblMsg.Text = "Sorry! Bots are not allowed!!";
            }
            else
            {
                lblMsg.Text = "All fields are required!!";
            }
        }
    }
}

1 个答案:

答案 0 :(得分:2)

取消注释该行

//cmd.ExecuteNonQuery();

如果没有这条线,它将无法正常工作。

顺便说一下,这个:

SqlCommand verifica = new SqlCommand();
verifica.CommandText = "select * from [Users]";
verifica.Connection = con;

SqlDataReader rd = verifica.ExecuteReader();
while (rd.Read())
{
    if (rd[1].ToString() == tbUname.Text || rd[3].ToString() == tbEmail.Text)
    {
        flag = true;
        break;
    }
}

if (flag == true)
{
    if (rd[1].ToString() == tbUname.Text)
    {
        lblMsg.Text = "Username already exists!";
    }

    if (rd[3].ToString() == tbEmail.Text)
    {
        lblMsg.Text = "Email already exists in the database!";
    }
}

是一个在DBMS上运行时性能更高的查询。您可能希望将其更改为以下内容:

SELECT [Username], [Email] 
FROM [Users] 
WHERE [Username] = @Username OR [Email] = @Email

请使用SqlCommand.Prepare()准备查询,而不是查询字符串。你现在这样做的方式,你很容易SQL Injection

更新

根据您的更新,您的真正问题是verificard仍在使用con。你需要处理这些,例如:

using (SqlConnection con = new SqlConnection(CS))
{
    con.Open();

    bool userNameExists = false;
    bool emailExists = false;

    using(SqlCommand verifica = new SqlCommand())
    {       
        //Update this query with the hints above
        verifica.CommandText = "select * from [Users]";
        verifica.Connection = con;

        using(SqlDataReader rd = verifica.ExecuteReader())
        {           
            while (rd.Read())
            {
                if (rd[1].ToString() == tbUname.Text)
                { 
                    userNameExists = true;
                    break;
                }
                else if (rd[3].ToString() == tbEmail.Text)
                {
                    emailExists = true;
                    break;
                }
            }
        }
    }

    if (userNameExists)
    {
        lblMsg.Text = "Username already exists!";
    }
    else if (emailExists)
    {
        lblMsg.Text = "Email already exists in the database!";
    }
    else
    {
        //You should update this part too, someone could choose the username 
        // "x','','U'); DROP TABLE [Users]; --" and do a lot of damage this way
        SqlCommand cmd = new SqlCommand("insert into Users values('" + tbUname.Text + "','" + EncryptPassword(tbPass.Text) + "','" + tbEmail.Text + "','" + tbName.Text + "','" + tbHoneypot.Text + "','U')", con);
        cmd.ExecuteNonQuery();
        lblMsg.Text = "Congratulations! Registration complete!!";
        lblMsg.ForeColor = Color.Green;
        Response.Redirect("~/Login.aspx");
    }
}

警告

图片用户选择名称x','','U'); DROP TABLE [Users]; --。您的查询会以现在的方式发生什么?

Convert.ToBase64String不是加密。它是编码,可以很容易地反转。请改用 Hash 。结合上面提到的问题,人们可以轻松阅读所有用户的电子邮件地址和密码(他们当然还有其他帐户,只有这种组合)。

最后的注释

如果只是取消注释一行解决问题而导致另一个问题,那么你就没有修复它 - 你只是引起了另一个问题。

在这种情况下,您的原始问题是

  

已经有一个与此命令关联的打开DataReader,必须先关闭它。

深思熟虑:您的SqlDataReaderClose方法。