Аутентификация для пароля не работает с использованием внешнего текстового файла - PullRequest
1 голос
/ 21 января 2020

Мой внешний текстовый файл, содержит имена пользователей и пароли в форме:

username1
password1
username2
password2

Он не сравнивает пароль, введенный с паролем в файле по какой-то причине. Вот код:

    userdata.open("userdata.txt");
    while(getline(userdata, temp))
    {
        counter++;
        if(counter % 2 == 1)
        {
            usernames.push_back(temp);
        }
    }
    cout<<"Please enter your username: ";
    cin>>username;
    for(int i = 0; i < usernames.size(); i++)
    {
        if(username == usernames[i])
        {
            usernameMatch = true;
            break;
        }
    }
    while(usernameMatch == false)
    {
        cout<<"\nInvalid Login! Please re-input your username: ";
        cin>>username;
        for(int i = 0; i < usernames.size(); i++)
        {
            if(username == usernames[i])
            {
                usernameMatch = true;
                break;
            }
        }
    }
    while(getline(userdata, temp))
    {
        counter++;
        if(counter % 2 == 0)
        {
            passwords.push_back(temp);
        }
    }
    cout<<"\nPlease enter your password: ";
    cin>>password;
    for(int i = 0; i < passwords.size(); i++)
    {
        if(password == passwords[i])
        {
            passwordMatch = true;
            break;
        }
    }
    while(passwordMatch == false)
    {
        cout<<"\nInvalid Login! Please re-input your password: ";
        cin>>password;
        for(int i = 0; i < passwords.size(); i++)
        {
            if(password == passwords[i])
            {
                passwordMatch = true;
                break;
            }
        }
    }
    cout<<"\nLogin Successful!"<<endl;
        userdata.close();

Проверка имени пользователя работает, но часть проверки пароля не работает и просто продолжает возвращать «Invalid Login! Please re-input your password:», когда я ввожу правильный пароль.

Я новичок здесь, пожалуйста, скажите мне, если я что-то пропустил. Кроме того, я могу использовать только включенные библиотеки, так как мы не узнали других, кроме ctype.h

1 Ответ

0 голосов
/ 22 января 2020

К сожалению, у нас нет всего соответствующего кода. Исходя из того, что вы предоставили, я бы предположил, что temp, username и password - все string, а usernames и passwords - vector<string>.

First потенциальные проблемы

Сначала проверьте, что вы явно инициализировали counter=0. Если вы забыли эту инициализацию, это случайная игра.

Тогда, если ваш username или password может содержать пробел , ваш cin>>xxx будет не синхронизирован c, поскольку он будет рассматривать это как два разных входы. Итак, если правило состоит из одной записи в строке, прочитайте с getline(cin, xxx)

Серьезная проблема при чтении вашего файла

Вы намереваетесь сначала прочитать ваш файл while, чтобы отфильтровать имена пользователей в нечетных строках вы снова читаете файл, чтобы отфильтровать пароли в четных строках. Но:

  • Ваш while-l oop выходит с потоком userdata в случае ошибки: что бы вы ни делали, вы не сможете ничего читать, пока не наберете userdata.clear() ошибка
  • В любом случае, вы никогда не перематываете файл назад. Таким образом, getline завершится ошибкой даже после сброса ошибок, потому что вы все равно будете помещены в конец файла. Так что вам нужно userdata.seekg(0);, чтобы перемотать.
  • Наконец, вы никогда не обнуляете счетчик на 0. Таким образом, ваша нечетная / четная проверка завершится неудачно, если число строк в файле нечетное (и пустой строки в конце достаточно, чтобы это произошло.

Гораздо проще было бы прочитать файл за один проход без перемотки:

while(getline(userdata, temp))
{
    counter++;
    if(counter % 2 == 1)    // if odd 
    {
        usernames.push_back(temp);
    }
    else                    // if even
    {
        passwords.push_back(temp);
    } 
}

И до финиша sh, нарушение безопасности: -)

Сначала вы проверяете, соответствует ли один из пользователей имени пользователя. Хорошо. Затем вы проверяете, соответствует ли пароль a пароль, любой пароль в файле, а не обязательно пароль, соответствующий имени пользователя:

  • Это означает, что законный пользователь может выдавать себя за любого другого пользователя системы, не зная его пароля!
  • Хуже: если у любого пользователя слабый пароль, это может быть взломана вся система !!!

Правильный способ - найти пользователя, сохранить его индекс ( это означает, что я должен быть определен за пределами l oop), и после ввода пароля вы проверяете, совпадает ли пароль с паролем в тот же индекс .

Теперь, спрашивая имя пользователя и сообщение о том, что имя пользователя не совпадает, прежде чем спрашивать пароль, делает работу для хакера, поскольку сразу становится ясно, какие данные неверны.

Правильный способ сделать эту проверку - спросить имя пользователя и пароль, а затем выполнить проверку и просто сказать, что логин неверен (поэтому потенциальный злоумышленник не знает, является ли это имя пользователя или пароль или оба не правы):

cout<<"Please enter your username: ";
getline(cin,username);
cout<<"\nPlease enter your password: ";
getline(cin,password);
for(int i = 0; i < usernames.size(); i++)
{
    if(username == usernames[i])
    {
        usernameMatch = true;
        passwordMatch = (password == passwords[i]);
        break;
    }
}
while (!usernameMatch || !passwordMatch) 
...
...