Форум программистов, компьютерный форум, киберфорум
Наши страницы
LostCoast
Войти
Регистрация
Восстановить пароль
Рейтинг: 3.00. Голосов: 2.

Обучающая статья по использованию асинхронных сокетов. Авторизация.

Запись от LostCoast размещена 17.12.2012 в 09:46
Обновил(-а) LostCoast 17.12.2012 в 09:53
Метки c-sharp

Содержание:
  1. Базовые функции
    1. Введение
    2. Передача данных
    3. Регистрация
    4. Авторизация
    5. Оптимизация
  2. Возможности для клиентов
    1. Изменение архитектуры
    2. Передача сообщений между клиентами
    3. Статус клиентов
    4. Список пользователей
    5. Передача файлов
Авторизация.

Часть 1. Подготовка сервера.

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

C#
1
2
3
private int pass_status;   //статус пароля
private enum PASSWORD        : int { NO_AUTH, LOGIN_SENT, PASS_PROMPTED, RECEIVED, OK, INVALID };
private string AUTH = "_CMD_AUTH";  //служит сигналом о начале авторизации клиента
Эти переменные будут выполнять то же самое, что и registr_status и REGISTRATION, и REG. Переменные у нас есть, пора вносить изменения в методы. Сначала изменим конструктор, а точнее добавим в нем инициализацию переменной pass_status:

C#
1
this.pass_status = (int)PASSWORD.NO_AUTH;
Метод CheckReceiveData будет выглядеть следующим образом:

C#
1
2
3
4
5
6
7
8
9
10
private void CheckReceiveData(string data)
        {
            if (this.pass_status != (int)CONECTIONSTATUS.OK)
            {
                if (data == AUTH)
                    this.conn_status = (int)CONECTIONSTATUS.AUTH;
                else if (data == REG)
                    this.conn_status = (int)CONECTIONSTATUS.REGISTR;
            }
        }
Теперь нам надо проверять не только запрос на регистрацию, но и на авторизацию, поэтому добавлена еще одна проверка. Следующие изменения ждут метод ReceiveCallBack. В нем надо добавить проверку на запуск авторизации и разрешения на прием простых сообщений, изменения будут происходить в последнем операторе if :

C#
1
2
3
4
5
6
             if (this.conn_status == (int)CONECTIONSTATUS.AUTH)
                    HandleAuthorize(cmd, this.pass_status);
             else if (this.conn_status == (int)CONECTIONSTATUS.REGISTR)
                    HandleRegistration(cmd, this.regist_status);
             else if (this.conn_status == (int)CONECTIONSTATUS.OK)
             HandleReceiveData(cmd);
Готово. Мы написали обработку поступающих сообщений. Но как вы могли заметить, метод HandleAuthorize у нас не реализован. Приступим. На этот раз я не буду расписывать очень подробно всю его логику, так как он делает то же самое, что и метод HandleRegistraion, за исключением того, что он авторизовавыет пользователя. Код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
private void HandleAuthorize(string data, int status)
        {
            if (status == (int)PASSWORD.NO_AUTH)
            {
                this.pass_status = (int)PASSWORD.LOGIN_SENT;
                Send("login: ");
                return;
            }
            if (status == (int)PASSWORD.LOGIN_SENT)
            {
                this.login = data;
                this.pass_status = (int)PASSWORD.PASS_PROMPTED;
                Send("password: ");
                return;
            }
            if (status == (int)PASSWORD.PASS_PROMPTED)
            {
                this.password = data;
                this.pass_status = status = (int)PASSWORD.RECEIVED;
            }
            if (status == (int)PASSWORD.RECEIVED && CheckUser(this.login, this.password, false))
            {
                this.pass_status = (int)PASSWORD.OK;
                this.conn_status = (int)CONECTIONSTATUS.OK;
                Console.WriteLine("Authorise completed!");
                Send("OK\n\r");
            }
            else
            {
                this.pass_status = (int)PASSWORD.NO_AUTH;
                Send("Invalid password\n\r");
                Console.WriteLine("Bad password or login");
            }
        }
Метод HandleAutorize не использует какие-либо дополнительные методы. При получении логина и пароля от пользователя, сравнивает тем же самым методом CheckUser существование зарегистрированного пользователя. Также он изменяет значение переменной conn_status на OK, что разрешает серверу принимать любые сообщения.
Для эксперимента сделаем снова из нашего сервера эхо-сервер. Для этого достаточно удалить вызов метода Receive в методе HandleReceiveData(string data), и написать следующую строчку:

C#
1
Send(data + '\n');
Мы будем просто отправлять обратно то, что получили. Заметьте на прибавление символа ‘\n’. Он нужен нам, так как пользователь принимает от нас сообщения методом Console.Write, который не переводит каретку на новую строку. Мы это делали для того, чтобы ввод логина и пароля выглядел немного естественным, как на других консольных приложениях.

Часть 2. Добавление авторизации и отправки сообщений на стороне клиента.

Сервер мы научили производить авторизацию, а вот клиента отправлять запросы на авторизацию - нет. Для начала переместимся в проект ConsoleClient, в главный класс программы добавим переменную AUTH и присвоим ей значение _CMD_AUTH, ее можно разместить рядом с переменной REG:

C#
1
string AUTH = "_CMD_AUTH";
Осталось добавить реализацию меню. Сделаем рабочими в нашем switch пункты меню 2 и 3. Вам надо просто добавить case 2, case 3 и реализовать их. Код:

C#
1
2
3
4
5
6
7
8
9
10
11
12
   
                    case 2:
                        client.Send(AUTH);
                        string send_auth = Console.ReadLine();
                        client.Send(ToSHA1(send_auth));
                        send_auth = Console.ReadLine();
                        client.Send(ToSHA1(send_auth));
                        break;
                    case 3: 
                        Console.Write("Write message: ");
                        client.Send(Console.ReadLine());
                        break;
Готово. Можно запускать сервер и пытаться зайти на сервер под созданным вами пользователем, и попытаться отправить сообщение.
Размещено в Без категории
Просмотров 1026 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru