Правильный ли алгоритм авторизации на Session и Cookies?
Добрый день.
Я делаю на своем сайте авторизацию через сессии и куки. Я придумал алгоритм, но не уверен в том, что он правильный. Помогите, пожалуйста, его дополнить и исправить.
Алгоритм
Когда пользователь отправляет свой логин и пароль серверу, они проверяются и если все хорошо, то в суперглобальный массив $_SESSION добавляется элемент с индексом 'username', в который записывается логин пользователя и отправляется куки с тем же именем пользователя (вот в этом месте, мне кажется, есть какая-то сильная дырка в безопасности).
Далее, когда нужно получить информацию о клиенте (о том, вошел он на сайт или нет) я реализую такой алгоритм: 1) если есть кука с его именем, то добавляем сессию с его именем; 2) если есть сессия с его именем, то ничего не делаем (т.к. кука могла закончить свою жизнь из-за времени ее хранения); 3) если есть и кука и сессия с его именем, то никаких изменений не делаем; 4) если нет ни куки, ни сессии, то так же ничего не делаем.
Далее просто проверяем, существует ли элемент в $_SESSION$ с индексом 'username', и, если он существует, работаем с этим клиентом, как с авторизированным пользователем.
Я считаю, что этот алгоритм очень странный с точки зрения безопасности. Помогите, пожалуйста, довести его до ума.
А зачем кукис слать пользователю? Просто запоминайте в сессии все необходимые параметры, веб-сервер сам пришлет phpsessid и дальше пользователь гулять будет только с ним. Ну и если так заботитесь о безопасности — привязка идентификатора сессии к IP и/или юзерагенту будет нелишней.
Если внимательно прочесть документацию и правильно все использовать, то ни чего при перезагрузке не обнуляется.
«Если несмотря на все ваши действия телевизор не включается, прочтите же наконец инструкцию!» (с)
Поэтому прочтите же инструкцию и повторите, что там описано www.php.net/manual/ru/session.examples.php ибо в PHP это все давно уже и нормально реализовано и работает, проверено тысячами программистов использующих сессии.
1) если есть кука с его именем, то добавляем сессию с его именем
Значит выставив себе куку с любым именем, я буду залогинен под этим пользователем.
Чего думать над велосипедом, когда обычно если логин/пароль правильные — ставим в сессию юзернейм, и всё.
Хм, действительно, значит нужно что-то, что невозможно подставить просто-так.
У меня так и было, но очень уж не удобно после перезагрузки браузера опять авторизироваться.
Сессия тоже не хранится вечно, хотя если народу у вас логинится не много, то можно и похранить их хоть полгода. Вопрос лишь в том как много их накопится и какой средний размер данных в сессии. Для начала сойдет, ну а далее можно так.
Предложенный Вами алгоритм ошибочен в плане безопасности.
Обычно делают так:
1) Новый пользователь при регистрации задаёт пароль, который шифруется со случайной «солью». Пользователь отправляется в виде кук его ID(для ускорения запросов), login и шифрованный пароль. В базу записывается ID, login, соль и шифрованный пароль.
2) При авторизации проверяется куки, если они верные, то создаём сессию и помещаем в нее нужные данные. Если в кукак что-то не так, то удаляем их на сервере и на клиенте при помощи JS и перекидываем на форму авторизации.
3) При обновлении страницы сверяем данные кук и сессии, если всё верно, то работаем. Если нет, то очищаем сессию и авторизуемся через куки. Пароль в сессии не храним.
Даже если злоумышленник получит доступ к куке хэшированного пароля, он без соли его не расшифрует. А вот без хранения шифрованного пароля на клиенте при потере сессии придётся каждый раз переавторизоваться.
Обязательно привязывать сессию к IP. Для аутентификации черех куки, нужно как имя пользователя/ID так и какой-либо хэш (может быть и хэш пароля). Можно конечно для куки тоже делать хэш на базе IP, но при смене IP нужна будет аутентификация. Автоматический вход на сайт это всегда брешь в безопасности. Я для себя эту проблему решил так: если пользователь вошел через куку, то на защищенных страницах просим повторно ввести пароль.
Зачем вы сами cookie отправляете? Опять велосипедничаете… Если используете $_SESSION — то уже и session_start() используйте, она сама сгенерирует хеш и отправит cookie. А если делаете собственный механизм — то $_SESSION тут ни при чём.
А вообще — начните с документации
Спасибо, конечно, за ссылку. Она была бы уместна, если бы я написал «расскажите, как делать авторизацию на сессиях и куки», но я попросил немного другое: я попросил помочь мне уже с моим алгоритмом, который у меня есть.
>(вот в этом месте, мне кажется, есть какая-то сильная дырка в безопасности)
Одного id мало, паралельно при авторизации нужно генерировать случайную последовательность скажем из 5-6 символов, после чего хешировать, записать хеш в базу и поставить куку с этим хешем.
При смене страницы, проверять id и хеш клиента, с теми что в базе, если совпадают, значит пользователь тот же.
@chremushkin, при перезагрузке браузера сессия остается, это сессионная кука пропадает, решается настройкой которую я написал выше. А динамический IP не настолько уж динамический чтобы меняться пока юзер ходит по сайту.
Если надолго, тогда конечно случайный хэш при логине в куку, и пару тот же хэш + IP в базу. Только не одну пару как cheremushkin предлагает, а скажем 5-7 пар. И методом LIFO — последний вытесняет первый. По желанию можно предлагать параноику анлинкать все предыдущие компы.
denver, новый хеш генерируется при каждом логине, в результате, в системе останется последний залогененый, хакерства здесь совершенно не вижу… cheremushkin, Ну вариант «что, я приду к другу Васе, посмотрю у него эту куку, потом дома я смогу зайти под его логином» прокатит… Но тут напрашитвается ещё один вопрос. А если злоумышленник узнает пароль?
Именно, почему я считаюсь не «тем же самым пользователем» когда пытаюсь войти на работе и дома. Или дома на телефоне и на компе. Поберегите нервы своим пользователям :)
denver, новый хеш генерируется при каждом логине, в результате, в системе останется последний залогененый, хакерства здесь совершенно не вижу… cheremushkin, Ну вариант «что, я приду к другу Васе, посмотрю у него эту куку, потом дома я смогу зайти под его логином» прокатит… Но тут напрашитвается ещё один вопрос. А если злоумышленник узнает пароль?
denver, новый хеш генерируется при каждом логине, в результате, в системе останется последний залогененый, хакерства здесь совершенно не вижу… cheremushkin, Ну вариант «что, я приду к другу Васе, посмотрю у него эту куку, потом дома я смогу зайти под его логином» прокатит… Но тут напрашитвается ещё один вопрос. А если злоумышленник узнает пароль?
denver, новый хеш генерируется при каждом логине, в результате, в системе останется последний залогененый, хакерства здесь совершенно не вижу… cheremushkin, Ну вариант «что, я приду к другу Васе, посмотрю у него эту куку, потом дома я смогу зайти под его логином» прокатит… Но тут напрашитвается ещё один вопрос. А если злоумышленник узнает пароль?