Estoy trabajando en el proyecto de C# y soy nuevo en esto de la tecnología.

Quiero leer algunos datos de SQL Server 2008, y escribir el siguiente código

public User select(string username, string password)
{
    string connection = ConfigurationManager.ConnectionStrings["lawyersDBConnectionString"].ConnectionString.ToString();
    string sql = string.Format("select * from users where userName = '{0}' and password = '{1}'", username, password);

    SqlConnection con = new SqlConnection();            
    con.ConnectionString = connection;

    DataSet ds = new DataSet();
    SqlDataAdapter da = new SqlDataAdapter(sql, con);            

    User user = new User();
    DataRow dr;

    try
    {
            da.Fill(ds);
            dr = ds.Tables[0].Rows[0];

            user.Id = Convert.ToInt16(dr["userID"]);                
            user.FirstName = (string)dr["firstName"];
            user.LastName = (string)dr["lastName"];
            user.Email = (string)dr["email"];
            user.Username = (string)dr["userName"];
            user.Password = (string)dr["password"];
            user.type = (string)dr["type"];

            return user;
    }
    catch (Exception ex)
    {                
            return null;
    }
}//end of select method

Pero yo había leído un artículo acerca de la inyección de SQL, y quiero usar los parámetros SQL para evitar esto, pero no sé cómo.

Se refieren a Steve respuesta – es la de la derecha. Pero preste mucha atención a cómo se utiliza el using instrucciones para asegurarse de que todos los objetos son eliminados adecuadamente – es importante.

OriginalEl autor Fadi Khalil | 2013-09-11

2 Comentarios

  1. 9

    Este es un sencillo de renovación en su código. No probado, pero esencialmente consiste en la adición de la instrucción de uso en torno a la disposición de los objetos y el uso de un SqlCommand con su colección de parámetros

    string connection = ConfigurationManager.ConnectionStrings ["lawyersDBConnectionString"].ConnectionString.ToString();
    string sql = "select * from users where userName = @uname and password = @pwd";
    
     DataSet ds = new DataSet();
     using(SqlConnection con = new SqlConnection(connection))
     using(SqlCommand cmd = new SqlCommand(sql, con))
     {
        con.Open();
        cmd.Parameters.AddWithValue("@uname", username);
        cmd.Parameters.AddWithValue("@pwd", password);
    
        using(SqlDataAdapter da = new SqlDataAdapter(cmd))
        {
             User user = new User();
             DataRow dr;
             da.Fill(ds);
             dr = ds.Tables[0].Rows[0];
    
             user.Id = Convert.ToInt16(dr["userID"]);                
             user.FirstName = (string)dr["firstName"];
             user.LastName = (string)dr["lastName"];
             user.Email = (string)dr["email"];
             user.Username = (string)dr["userName"];
             user.Password = (string)dr["password"];
             user.type = (string)dr["type"];
             return user;
        }
    }

    Cuenta de cómo el comando de texto no contiene directamente a las cadenas de usuario y contraseña, sino un simple marcador de posición de parámetro (@uname and @pwd). Estos marcadores son referidos como los parámetros de nombre a la hora de añadir parámetros a la SqlCommand colección.

    Buscando en el uso de los datos recuperados yo sugiero que usted mire simple ORM herramientas como Dapper que directamente podría traducir todos de este código en el objeto de Usuario

    Caramba, me pegaba a él 😛
    Perfectamente aplicado

    OriginalEl autor Steve

  2. 1

    Curiosamente, la forma de Cadena.El formato de las obras no se diferencia mucho de los parámetros SQL. La única diferencia real es el que se especifica el tipo de datos de cada parámetro es el que permite que el SQLCommand para desinfectar correctamente (lea: evitar la inyección sql) su entrada del usuario.

    He aquí un ejemplo de cómo se podría modificar el código para que utilice los Parámetros SQL.

    using (SqlConnection connection = new SqlConnection(connectionString))
    {
        connection.Open();
        using (SqlCommand command = new SqlCommand("select * from users where userName = @pUsername and password = @pPassword", connection))
        {
            command.Parameters.Add(new SqlParameter("pUsername", username));
            command.Parameters.Add(new SqlParameter("pPassword", password));
    
            DataSet ds = new DataSet();
            SqlDataAdapter da = new SqlDataAdapter(command);  
    
            //The rest of your code here...
         }
    }

    Un par de cosas que me gustaría mencionar:

    1. Los nombres de usuario son normalmente sensibles a mayúsculas y minúsculas por lo que la consulta probablemente debería usar un LIKE o UCASE() comparación para buscar el nombre de usuario.
    2. Es evidente a partir de la consulta de que la contraseña no es hash o salados. Esto es muy malo. Leer sobre el hashing de contraseñas. https://crackstation.net/hashing-security.htm
    3. Básicamente lo que se está creando aquí se llama un objeto relacional manager. A menos que usted esté específicamente interesados en aprender a desarrollar uno le recomiendo que utilice uno que ha sido probado y comprobado. Personalmente creo que el uso de fluent. Hibernate fue escrito como un ORM para Java y nHibernate es muy popular .Net applications. Entity Framework de Microsoft es ORM. Yo no creo que sea muy a la par con nHibernate, pero está mejorando constantemente.

    OriginalEl autor Spencer Ruport

Dejar respuesta

Please enter your comment!
Please enter your name here