-4

业务接入层:

    public static int login(string userlogin, string pwdlogin)
    {
        SqlConnection con = new SqlConnection();
        con.ConnectionString = GetConnectionString();
        con.Open();
        int id = 0;
        string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = selectstr;
        cmd.CommandType = System.Data.CommandType.Text;
        cmd.Connection = con;
        id = cmd.ExecuteNonQuery();
        cmd = null;
        con.Close();
        return id;
    }

登录.cs

 protected void Button1_Click(object sender, EventArgs e)
    {
        int id = BusinessAccessLayer.login(userlogin.Text.Trim(), pwdlogin.Text.Trim());
        if (id > 0)
        {
            message.Text = " valid";
        }
        else
        {
            message.Text = "in valid";
        }   
    }
4

3 回答 3

6

好的,这里有很多问题:

1)using即使抛出异常,您也应该使用语句来确保关闭连接和命令

2) 您应该使用参数化 SQL 而不是将值直接放入您的 SQL 语句中,以避免 SQL 注入攻击

3)您似乎以纯文本形式存储密码。不要那样做。使用加盐哈希或类似的东西(理想情况下计算速度很慢)。

4) 你忽略了 .NET 命名约定;方法应该在 PascalCase

5) 您的 SQL 从不查看任何与用户 ID 相关的字段。不清楚您希望ExecuteNonQuery返回什么,但如果您想要实际的 ID,则需要在 SQL 中引用它。(即使最初你只是想知道用户的密码是否有效,我强烈怀疑在某些时候你会想要使用真实的用户 ID,所以你应该让你的代码返回它。如果你真的只想要知道密码是否有效,您应该将方法的返回类型更改为bool。)

6)ExecuteNonQuery当您的命令显然查询时,您正在使用。使用ExecuteReaderExecuteScalar代替。(ExecuteNonQuery用于插入、删除和更新语句,它会返回受命令影响的行数。)

所以像:

public static int Login(string user, string password)
{
    using (var conn = new SqlConnection(GetConnectionString()))
    {
        conn.Open();
        string sql = "select Id, PasswordHash from logins where Username=@Username";
        using (var command = new SqlCommand(sql))
        {
            command.Parameters.Add("@Username", SqlDbType.NVarChar).Value = user;

            using (var reader = command.ExecuteRead())
            {
                if (reader.Read())
                {
                    int id = reader.GetInt32(0);
                    string hash = reader.GetString(1);
                    // TODO: Hash provided password with the same salt and compare
                    // results
                    if (CheckPassword(password, hash))
                    {
                        return id;
                    }
                }
                return 0; // Or use an int? return type and return null
            }
        }
    }
}
于 2013-03-11T07:01:20.007 回答
0

如果需要结果,则不能使用 .ExecuteNonQuery。使用 .ExecuteReader。

public static int login(string userlogin, string pwdlogin)
{
    SqlConnection con = new SqlConnection();
    con.ConnectionString = GetConnectionString();
    con.Open();
    int id = 0;
    string selectstr = "SELECT UserId FROM Registration WHERE UserName = '" +    userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
    SqlCommand cmd = new SqlCommand();
    cmd.CommandText = selectstr;
    cmd.CommandType = System.Data.CommandType.Text;
    cmd.Connection = con;

    SqlDataReader reader = cmd.ExecuteReader();
    reader.Read();
    id = reader.GetInt32("UserId");

    reader.Close();
    con.Close();

    return id;
}
于 2013-03-11T07:00:01.557 回答
0

ExecuteNonQuery用于 For UPDATE、INSERT 和 DELETE 语句。对于 SELECT 语句,使用ExecuteReader

public static int login(string userlogin, string pwdlogin)
{
        SqlConnection con = new SqlConnection();
        con.ConnectionString = GetConnectionString();
        con.Open();
        int id = 0;
        string selectstr = "SELECT UserName, Password FROM Registration WHERE UserName = '" + userlogin.Trim() + "' AND Password = '" + pwdlogin.Trim() + "'";
        SqlCommand cmd = new SqlCommand();
        cmd.CommandText = selectstr;
        cmd.CommandType = System.Data.CommandType.Text;
        cmd.Connection = con;
        SqlDataReader reader = cmd.ExecuteReader();
        while (reader.Read())
        {
               id++; 
        }
        cmd = null;
        reader.Close();
        con.Close();
        return id;
}
于 2013-03-11T07:02:44.347 回答