C # Форма входа, кнопка входа, безопасность - PullRequest
3 голосов
/ 03 апреля 2019

Итак, я новичок в VS и C #, я самоучка, чтобы лучше понять бэкэнд продукта, с которым я работаю. Я создал небольшую базу данных с некоторой информацией и формой для входа. Кажется, все компилируется правильно, но это безопасный способ сделать это или есть другой способ, любая помощь приветствуется. Спасибо.

 private void button2_Click(object sender, EventArgs e)
    {

        SqlCommand cmd = new SqlCommand("select * from tbladmin where username=@username and password=@password", sqlcon);
        cmd.Parameters.AddWithValue("@username", txtusername.Text);
        cmd.Parameters.AddWithValue("@password", txtpassword.Text);
        SqlDataAdapter sda = new SqlDataAdapter(cmd);
        DataTable dtbl = new DataTable();
        sda.Fill(dtbl);


        try
        {

            if (dtbl.Rows.Count > 0)
            {
                if (dtbl.Rows[0]["role"].ToString() == "Admin")
                {
                    SqlCommand cmd2 = new SqlCommand("select date from tbladmin where username=@username and password=@password", sqlcon);
                    cmd2.Parameters.AddWithValue("@username", txtusername.Text);
                    cmd2.Parameters.AddWithValue("@password", txtpassword.Text);
                    SqlDataAdapter sda2 = new SqlDataAdapter(cmd2);
                    DataTable dss = new DataTable();
                    sda2.Fill(dss);
                    String value2 = dss.Rows[0][0].ToString();
                    DateTime date = DateTime.Parse(dss.Rows[0][0].ToString());
                    Class1.Txtusername = txtusername.Text;
                    Debug.WriteLine("value is :   " + value2);

                    if (date.AddDays(90) < DateTime.Now)
                    {
                        Changpassad obj2 = new Changpassad();
                        this.Hide();
                        obj2.Show();
                    }
                    else
                    {

                        calladmin obj = new calladmin(dss.Rows[0][0].ToString());
                        this.Hide();
                        obj.Show();
                    }
                }
            }
            else if (dtbl.Rows.Count == 0)
            {
                SqlCommand cmd3 = new SqlCommand("select date from tblcallcenter where username=@username and password=@password", sqlcon);
                cmd3.Parameters.AddWithValue("@username", txtusername.Text);
                cmd3.Parameters.AddWithValue("@password", txtpassword.Text);
                SqlDataAdapter sda2 = new SqlDataAdapter(cmd3);
                DataTable dss = new DataTable();
                sda2.Fill(dss);
                String value2 = dss.Rows[0][0].ToString();
                DateTime date = DateTime.Parse(dss.Rows[0][0].ToString());

                Debug.WriteLine("value is :   " + value2);

                if (date.AddDays(90) < DateTime.Now)
                {
                    Changpass obj2 = new Changpass()/;
                    this.Hide();
                    obj2.Show();
                }
                else
                {
                    SqlCommand cmd4 = new SqlCommand("select user_id , username from tblcallcenter where username=@username and password=@password", sqlcon);
                    cmd4.Parameters.AddWithValue("@username", txtusername.Text);
                    cmd4.Parameters.AddWithValue("@password", txtpassword.Text);
                    SqlDataAdapter From_sda = new SqlDataAdapter(cmd4);
                    DataTable From_ds = new DataTable();
                    From_sda.Fill(From_ds);
                    String value1 = From_ds.Rows[0][1].ToString();
                    int id = int.Parse(From_ds.Rows[0][0].ToString());

                    Debug.WriteLine("value is :   " + value1);
                    Class1.Txtusername = txtusername.Text;
                    this.Hide();
                    SqlCommand cmd5 = new SqlCommand("select  [from], Take from tblcallcenter where username=@username and password=@password", sqlcon);
                    cmd5.Parameters.AddWithValue("@username", txtusername.Text);
                    cmd5.Parameters.AddWithValue("@password", txtpassword.Text);
                    SqlDataAdapter sda1 = new SqlDataAdapter(cmd5);
                    DataTable ds = new DataTable();
                    sda1.Fill(ds);
                    Callcenter1 obj = new Callcenter1(ds.Rows[0][0].ToString(), ds.Rows[0][1].ToString());
                    this.Hide();
                    obj.Show();
                }
            }

            else
            {
                MessageBox.Show("Invalid Login try checking Useraname Or Password !", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
        catch (Exception)
        {
            MessageBox.Show("Invalid Login try checking Useraname Or Password !", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

Ответы [ 3 ]

8 голосов
/ 10 апреля 2019

1. Не забывайте принцип единоличной ответственности

Ответственность за вашу форму лежит только на представлении пользовательского интерфейса. Должна ли ваша форма знать, как вы храните свои данные? Отвечает ли ваша форма, чтобы знать, когда пользователь должен изменить свой пароль? Нет.

Каждый класс должен нести одну ответственность. У вас может быть класс AuthenticationService, отвечающий за аутентификацию пользователя, и класс UserRepository для хранения / извлечения пользователей в базе данных. Например, это может быть ваш обработчик нажатия кнопки button2:

private void button2_Click(object sender, EventArgs e)
{
    var authenticationService = new AuthenticationService(sqlcon);


    try
    {
        var user = authenticationService.AuthenticateUser(txtusername.Text, txtpassword.Text);

        if (user.Date.AddDays(90) < DateTime.UtcNow)
        {
            Changpassad obj2 = new Changpassad();
            this.Hide();
            obj2.Show();

            return;
        }

        if (user.IsAdmin)
        {
            calladmin obj = new calladmin(user);
            this.Hide();
            obj.Show();
        }
        else
        {
            Callcenter1 obj = new Callcenter1(user);
            this.Hide();
            obj.Show();
        }

    }
    catch (Exception)
    {
        MessageBox.Show("Invalid Login try checking Useraname Or Password !", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
}

Вы можете пойти дальше этого принципа, и ваши методы также будут нести единоличную ответственность. Например, в приведенном выше коде я по-прежнему извлекаю код, проверяющий необходимость изменения паролей и код, ответственный за открытие правильной формы.

Вы уже используете параметры в своем запросе SQL. Хорошо. Вы устойчивы к SQL-инъекциям .

Как только вы познакомитесь, я также рекомендую рассмотреть ORM, такие как Entity Framework , чтобы упростить процесс.


2. Не хранить незашифрованный пароль в базе данных

Серьезно. Никогда не делай этого.

Всегда старайтесь не управлять паролем пользователя. Если вам абсолютно необходимо, в .Net Framework есть встроенные классы для этого. Вот несколько ссылок, но быстрый поиск должен дать гораздо больше.

Если по каким-либо причинам вы не используете тезисы и решили самостоятельно управлять паролем. Вам нужно найти криптографически безопасный алгоритм хеширования ( не md5 , как в другом ответе). И вам нужно использовать уникальную «соль» для каждого хэша пароля. Я оставлю эту ссылку здесь, поскольку она выходит за рамки вашего текущего вопроса:

- Хэш-пароли в ASP.NET Core - Разница между кодированием, шифрованием и хешированием


3. Дайте значимое имя вашей переменной.

Что такое button2? Что такое obj2? Что означает ds.Rows[0][0].ToString()? Вы должны попытаться дать представительное имя вашей переменной. Как насчет btnLogin, callAdminForm, ...

Пока мы здесь, я рекомендую вам прочитать Общие правила именования C # . Например, соглашение о присвоении имен для классов - PascalCase. Это должно быть CallAdmin, а не calladmin.


4. Почему у вас есть имя пользователя / пароль, хранящиеся в нескольких таблицах?

Почему пользователи хранятся в tbladmin и tblcallcenter?

Как насчет одного tblUsers и либо столбца, либо связанной таблицы, определяющей роль пользователя? Это будет легче поддерживать в долгосрочной перспективе. Зачем делать что-то дважды, если ты мог сделать это один раз?

2 голосов
/ 10 апреля 2019

Вы можете заботиться о:

1- Хешировании пароля с использованием чего-то вроде:

CONVERT(VARCHAR(32), HashBytes('MD5', 'password'), 2)

2- Сравнение точных букв в верхнем или нижнем регистре.

Select * from tblcallcenter where password= @password COLLATE Latin1_General_CS_AS 

используя сопоставление с учетом регистра, чтобы убедиться, что пароль тот же

3 - Вы можете использовать некоторые новые технологии базы данных c #, такие как Entity Framework или более старые, такие как Typed Dataset или Linq, для sql, его легко и быстро разработать. Entity Framework , Типизированный набор данных , Linq to SQL

0 голосов
/ 09 апреля 2019

Не стоит смешивать все в одном классе.Попробуйте разбить эту задачу на несколько элементов:

  1. проверка ввода пользователя (это может быть отдельный метод в том же классе)
  2. отдельный класс (или, по крайней мере, метод), который обрабатывает DB.Вы должны передать информацию для входа и получить результат (достаточно true / false)
  3. уведомление о результате - отобразить сообщение о пустом имени пользователя / пароле, о неправильном входе в систему

Поверьте, это будетвам будет легче развивать его дальше.Удачи:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...