Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL връзката хвърля нулева препратка

Това не е отговор на NullReferenceException - все още работим по това в коментарите; това е обратна връзка за защитните части.

Първото нещо, което можем да разгледаме, е SQL инжекция; това е много лесно за поправяне - вижте по-долу (обърнете внимание, че съм подредил и някои други неща)

// note: return could be "bool" or some kind of strongly-typed User object
// but I'm not going to change that here
public string[] GetValidUser(string dbUsername, string dbPassword)
{
    // no need for the table to be a parameter; the other two should
    // be treated as SQL parameters
    string query = @"
SELECT id,email,password FROM tbl_user
WHERE [email protected] AND [email protected]";

    string[] resultArray = new string[3];

    // note: it isn't clear what you expect to happen if the connection
    // doesn't open...
    if (this.OpenConnection())
    {
        try // try+finally ensures that we always close what we open
        {
            using(MySqlCommand cmd = new MySqlCommand(query, connection))
            {
                cmd.Parameters.AddWithValue("email", dbUserName); 
                // I'll talk about this one later...
                cmd.Parameters.AddWithValue("password", dbPassword); 

                using(MySqlDataReader dataReader = cmd.ExecuteReader())
                {
                    if (dataReader.Read()) // no need for "while"
                                           // since only 1 row expected
                    {
                        // it would be nice to replace this with some kind of User
                        //  object with named properties to return, but...
                        resultArray[0] = dataReader.GetInt32(0).ToString();
                        resultArray[1] = dataReader.GetString(1);
                        resultArray[2] = dataReader.GetString(2);

                        if(dataReader.Read())
                        { // that smells of trouble!
                            throw new InvalidOperationException(
                                "Unexpected duplicate user record!");
                        }
                    }
                }
            }
        }
        finally
        {
            this.CloseConnection();
        }
    }
    return resultArray;
}

Сега може би си мислите, че "това е твърде много код" - разбира се; и съществуват инструменти, които да помогнат с това! Например, да предположим, че сме направили:

public class User {
    public int Id {get;set;}
    public string Email {get;set;}
    public string Password {get;set;} // I'll talk about this later
}

След това можем да използваме dapper и LINQ, за да вършат цялата работа вместо нас:

public User GetValidUser(string email, string password) {
    return connection.Query<User>(@"
SELECT id,email,password FROM tbl_user
WHERE [email protected] AND [email protected]",
      new {email, password} // the parameters - names are implicit
    ).SingleOrDefault();
}

Това прави всичко имате (включително безопасно отваряне и затваряне на връзката), но го прави чисто и безопасно. Ако методът връща null стойност за User , това означава, че не е намерено съвпадение. Ако е ненулев User екземпляр се връща - той трябва да съдържа всички очаквани стойности само като се използват конвенции, базирани на имена (което означава:имената на свойствата и имената на колоните съвпадат).

Може да забележите, че единственият код, който остава, е действително полезен код - не е скучен водопровод. Инструменти като dapper са ваш приятел; използвайте ги.

Накрая; пароли. Никога не трябва да съхранявате пароли. някога. Нито веднъж. Дори не е криптиран. никога. Трябва само съхранявайте хешове на пароли. Това означава, че никога не можете да ги извлечете. Вместо това трябва да хеширате това, което потребителят предоставя и да го сравните със съществуващата хеширана стойност; ако хешовете съвпадат:това е пропуск. Това е сложна област и ще изисква значителни промени, но вие трябва да направите това . Това е важно. Това, което имате в момента, е несигурно.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Грешка в MySQL/Amazon RDS:нямате СУПЕР привилегии...

  2. MySQL Създаване на таблици с външни ключове, даващи errno:150

  3. cronjob четене от една база данни и писане в друга

  4. задаване на blob на нула с помощта на PreparedStatement

  5. Защо преименуването на колона в mysql отнема толкова време?