在登录页面3 - 轮胎架构中遇到麻烦

yas*_*ash -4 c# database-connection 3-tier

商务访问层:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

Login.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";
        }   
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 6

好的,这里有很多错误:

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

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

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

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
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)