@hbuser А какая разница? В статье речь о том, как это запилить с помощью Руби... Но суть-то от этого не меняется :) Хотите без Руби - там в комментах структура БД показана. В ней, точнее в первой таблице и есть суть.
create_table "posts", :force => true do |t|
t.string "title"
t.boolean "published"
t.integer "content_id"
t.string "content_type"
t.datetime "created_at"
t.datetime "updated_at"
end
Собственно, если бы не Руби - статью можно бы было сократить до этой самой структуры :) Фактически, речь идет просто об одной из возможностей денормализации модели данных.
Вам вряд ли подойдет. Я в глубоком тылу и ссылки мои, соответственно, тоже отсюда :) Ищите на месте, проявите инициативу, обзвоните фирмы... работу везде совершенно одинаково ищут - в интернет, по объявлениям, по знакомым.
path=/home/user/motion_files/files/$(date +%y -r $1)/$(date +%m -r $1h)/$(date +%d -r $1)
mkdir -p $path
if ! [[ `lsof $1` ]] ; then
mv $1 $path
fi
А то кто его знает, в какой конкретно момент оно попытается это провернуть и как эти файлы пишутся... если файл еще открыт (не дописан полностью), будет облом.
Хеш пароля храним только в БД и проверяем один раз, при логине, повторно вычислив его из пароля, введенного пользователем. Все! Больше он не не понадобится аж до следующего логина.
Если логин был успешный (т.е. хеш, вычисленный из присланного пароля совпал с тем, что хранится в БД), генерируем токен - другое (случайное, одноразовое) число. Вот его можем хранить в куке (или еще как-нибудь, например, в hidden поле - главное, чтоб браузер прислал нам его при следующем запросе) и в сессии (на сервере), чтоб когда придет этот самый запрос, можно было сравнить.
Это нужно, чтоб отличить "правильный" запрос (с токеном, который мы сами только что выдали) от "левого". Если совпадает - ОК, значит, это не "левый" запрос. Тогда генерируем новое случайное число, для следующего запроса, и т.д. Если же токен в запросе не совпадает с текущим токеном в сессии - убиваем вессию и снова требуем ввод пароля.
Ну, а идентификатор в БД - это то же ID пользователя, или username... что угодно! Его при успешном логине (в самом начале) просто сохраняем в сессии (один раз) и дальше пользуемся им для выборки из БД и т.д.
@vadimnekrasov нет, не значит. Когда пользователь впервые (при регистрации!) вводит пароль и отправляет его на сервер, сервер считает хеш, и сохраняет его (а не пароль) в БД. Впоследствии, когда пользователь вводит пароль (при логине), сервер снова считает хеш и сравнивает его со значением в БД. Если совпало (пользователь авторизован), сервер генерирует токен (который уже можно положить в куку) и запоминает его в сессии. Сам пароль вообще НИГДЕ не хранится. При следующем запросе сервер сравнивает значение токена в куке со значением в сессии, и если совпало - пользователь авторизован. Тогда генерируется новый токен, и т.д. по кругу, до тех пор, пока пользователь не разлогинится или сессия не закончится по таймаут. (Если же токен не совпал - сессия немедленно убивается и редирект на ввод пароля.) Таким образом время, за которое злоумышленник теоретически может угнать акк, сводится к минимуму: от получения ответа (с новым, одноразовым токеном) до следующего запроса пользователя. Угон, хоть и не исключается теоретически, но затрудняется настолько (особенно по сравнению с хранением пароля в куке), что для него уже нужны нехилая мотивация и возможности.
Это - просто пример обеспечения секюрити, адекватной уровню угрозы / ценности информации. Т.е. злоумышленнику принципиально не поможет ни угон куки, ни знание самого механизма секюрити, ни даже угон БД с сервера (!) - ему нужно еще как-то поднапрячся, чтоб угнать акк. Хранение пароля в куке - типичный пример security through obscurity. Такая система "безопасна" ровно до тех пор, пока злоумышленник не узнает, что она хранит пароль в куке :)
Ну дык, потому и говорят, что таки крадут. А крадут по двум причинам. Во-первых, это сравнительно просто... намного проще, чем украсть пароль, сохраненный браузером. Во-вторых, к сожалению, существует еще множество систем, разработчики которых рассуждая тиким простым, но неверным образом, и не понимая, что куки для этого не предназначены, таки помещают в них "секреты". А это печальное явление вызвано, в свою очередь, недостатком знаний и логическими ошибками в рассуждениях. Например, что о безопасности кук нужно заботиться - неверно! Нужно проектировать систему так, чтоб угон кук не компромитировал безопасность системы :) Или утверждение, что это, мол, забота пользователя... рассуждать таким образом - все раво, что согласиться с тем, что люки на дорогах можно и нужно оставлять открытыми, т.к. не падать в них - это забота пешеходов. Вы бы хотели ходить по таким дорогам?
Ну, и наконец - если речь зашла о паролях... их хранить вообще нельзя нигде, кроме головы пользователя. Хранить нужно только хеш, и только в одном месте - на сервере!
Этому можно верить или не верить, однако, как говорится, незнание закона не освобождает от ответственности :)
При extends методы можно не переопределять - только если наследуется от конкретного класса (т.е. если они уже где-то хоть раз были определены)! Если же наследуется от абстрактного класса, то либо и сам наследующий класс должен быть все еще абстрактным, либо таки придется метод имплементировать :) Тут фишка совсем в другом!
Наследование от абстрактных классов позволяет "размазать" имплементацию отдельных методов по разным уровням наследования. На каждом уровне имплементируем то, что к нему относится, а остальные методы оставляем абстрактными, и имплементируем их на других уровнях.
Интерфейс же требует, разумеется, имплементировать все - на то он и контракт. Так что, интерфейс используется именно для закрепления контракта, а абстрактный класс - для структурирования имплементации этого контракта.
@LittleMagic Очень на то похоже! Если у Вас есть под рукой отвертка-пробник (с неоновой лампочкой), приложите ее к флешке, а потом к контактам блока питания, отключенного от ноута (только по отдельности - не замкните их!) и посмотрите, не светится ли. А вообще, рекомендую лучше обратиться к специалисту на месте... во избежание, так сказать.
@LittleMagic Ну, если объяснять, не вдаваясь во всякие транзиенты, бурсты и спайки, можно сказать, что Вы (в зависимости от того, в чем именно причина) дополнительно заземляете девайс или создаете своим телом дополнительную паразитную ёмкость между "массой" и реальной землей, достаточную для того, чтоб ослабить эти шумы до уровня, когда их уже не слышно.
@another_dream Видите ли, если бы Вы привели нарисованый UML или ERD, можно бы было понять, что непонятно или подсказать, что неправильно... a так - это как партия в шахматы по переписке. У меня, лично, точно терпения не хватит... уж извините.
@Faint Видите ли: подобные железяки и сервисы есть, но все их объединяет то, что носимые части нужно подзаряжать, причем, раз в три дня - это еще нормально :) Так что, из реальных преимуществ искомых брелков перед телефонами остается только то, что их сложнее сломать или нечаяно отключить, и они немного компактнее телефонов.
Заранее извините за черный юмор, но мне кажется, что Вы напрасно так переживаете. Дело в том, что описанные на Хабре печальные события имели место быть до санкций. По идее, пока дело дойдет до отправки, процедура может принципиально упроститься уже на стороне отправителя :(
"Разделение страницы" идет там, где серверная часть, генерирующая страницу, выполнит flush(), т.е. пошлет клиенту очередную порцию данных в стриме. Где это произойдет, решает разработчик :) В книге просто обращается внимание читателя на тот факт, что не нужно колбасить, пока сгенерируется ВСЕ, а лучше отправлять готовые части по мере поступления. И еще на то, что "делить" нужно осмысленно, чтоб клиенту от этого была польза (ибо если послать, например, '<bo', а через час дослать 'dy>...</html>', то пользы от этого будет ноль).
Собственно, если бы не Руби - статью можно бы было сократить до этой самой структуры :) Фактически, речь идет просто об одной из возможностей денормализации модели данных.