nomadmoon: (Default)
Починил редактирование вещей (по наводке Павла) и сделал загрузку аватарок.

Аватарки, как и планировал, хранятся на другом сервере. Причешу код - напишу подробнее.

Всё еще бета-тест, но можно тестить новый функционал.
nomadmoon: (Default)
Возвращаясь к теме сопользования (корявое слово, но английское "шеринг" мне что то тоже не очень). Судя по тому что регитсрации на bral-otdal.ru были, а вопросов почти не было (кроме того что не работает редактирование вещей), стало быть в общем всё более менее работает.

Это радует. Редактирование я поправил, не сегодня завтра выложу. Также изменена перекодировка спецсимволов в данных в HTML-формат (угловые скобочки в > и тд) - раньше перекодировались при выводе, теперь будут перекодироваться при вводе. Избыточность получается небольшая, зато меньше нагрузка на проц, т.к. просматриваются данные куда чаще чем вносятся или редактируются.

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

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

Какие могут быть подводные камни? Или может быть есть способ лучше?
nomadmoon: (Default)
Я думал мой дизайн - говно, но вчера я зашел на Facebook...
В качестве эпиграфа.

Как вы могли заметить, http://bral-otdal.ru работает *звук вылетающей пробки шампанского*.

Давайте я расскажу вам о некоторых спорных решениях, которые я принял в процессе разработки:

1) Добавлена функция восстановления пароля (точнее генерации нового и отсылки на почту). А потом я подумал и решил раз уж пошла такая пьянка то давайте сделаем так что и при регистрации вместо придумывания пароля можно было бы поставить галочку "сгенерировать пароль и отправить мне на почту".

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

Потом я подумал и всё таки запилил механизм посылки друг другу личных сообщений.

3) Механика "открывания" вещей тоже односторонняя и цельнотянута из ЖЖ - ты видишь вещи тех, кто добавил тебя в друзья. Если ты кого то добавил в друзья, то они видят твои вещи. Точка.

4) Город. Я осознал что пользователи могут быть из разных городов, да.

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

Что там еще? Ах да

5) Дизайн. Одноколоночный, 320px шириной, для совместимости с мобильными устройствами, что, теоретически, должно позволить даже солидному владельцу айфона взять в аренду степлер. На практике, впрочем, как раз на айфоне оно и не проверялось, но на моём андроидном Highscreen-е под родным браузером, мобильным файрфоксом и оперой вроде всё ок. Для всё той же совместимости кнопки и ссылки расположены по возможности в отдалении друг от друга, чтобы легче в них целиться.

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

Пойду добавлю себе в вещи жёлтую уточку.

PS Самое главное то, ссылка на добавление меня в друзья:
http://bral-otdal.ru/index.php?s=add_friend&id=33
nomadmoon: (Default)
Вчера я выложил обновления на сайт, попытался авторизоваться и, без осбого, впрочем удивления, обнаружил что я забыл пароль. Так я пришел к тому что пора прикрутить систему восстановления паролей.

Я знаю несколько систем восттановления пароля - по ответу на секретный вопрос, на мыло и СМС-кой.

Ответ на секретный вопрос я не очень то люблю, поскольку я персона в значительной степени публичная то события моей жизни относительно известны.

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

Остаётся мыло. Мой любимый способ восстановления пароля, особенно когда надо ввести только мыло, потому что свой логин я на новом ресурсе тоже часто забываю, их у меня несколько. А основное мыло одно.

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

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

Тогда например почта vasya@ya.ru будет иметь хэш 12, но если мы передадим для востановления пароля, допустим, xaker@ya.ru, то тоже получим хэш 12, и письмо с новым паролем уйдет на почту хакеру. Побочный эффект от этого - при регистрации нового пользователя, если при проверке хэша емэйла мы получили коллизию с тем что уже сть в базе, то мы не можем об этом сообщать пользователю. Причем использовать динамическую соль для получения более уникального хэша мы тоже не можем, нам потом по этому хэшу еще искать строку в таблице, вообще то.

В общем варианты решения на первый взгляд такие:
1) Запрашивать при восстановлении пароля еще и логин (более мягкий вариант - запрашивать логин только если искомый хэш мыла встречается в таблице не единожды).

2) Уменьшать вероятность коллизии хешированием двумя разными алгоритмами и/или с разными статическими солями.

3) Не париться. Хранить емэйлы в открытом виде.

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

Дискас? Как вариант можете предложить какой то хороший метод восстановления пароля который мне еще неизвестен.
nomadmoon: (Default)
Опять таки это не 'кавычки за бабло', как могло бы показаться. Начнём с небольшой теории.

Тот кто понимает этот комикс может пропустить следующие пять абзацев:


Для остальных - краткий ликбез в SQL. SQL - это такой язык доступа к данным в базах данных. Он, в общем то, достаточно прост. Давайте приведем пример в стиле нашего комикса. Как бы выглядел запрос данных о студенте? Например так:

SELECT class, speciality, balls FROM students WHERE stud_name='Robert' AND curse='Physics';

переводится это почти дословно:
ВЫБРАТЬ класс, специальность, баллы ИЗ ТАБЛИЦЫ студенты ГДЕ имя_студня='Роберт' и курс='Физика';

Что же происходит в комиксе? Мама назвала сына Robert'; DROP TABLE students; -- и если это ввести в запрос получится:

SELECT class, speciality, balls FROM students WHERE stud_name='Robert'; DROP TABLE students; --' AND curse='Physics';

то есть

ВЫБРАТЬ класс, специальность, баллы ИЗ ТАБЛИЦЫ студенты ГДЕ имя_студня='Роберт'; УДАЛИТЬ ТАБЛИЦУ студенты;-- и курс='Физика';

В итоге база данных выбирает из таблицы все строки где имя_студня=Роберт, удаляет таблицу Студенты, а на остальное не смотрит, потому то две тире в SQL означают начало комментария и всё что дальше не интерпретируется. Как видим всё это смогло произойти потому что кавычка интерпретировалась не как буква, а как управляющий символ. Пример, конечно, утрированный, но всякое бывает. Используя такие ошибки можно и прочитать данные из базы данных, и что нибудь несанкционированно изменить. Обычно чтобы экранировать кавычку перед ней ставят управляющий символ / (слэш), а если в тексте есть сочетание /', то тогда спецсимвол слэш надо тоже экранировать спецсимволом слэш... Короче ну его это всё нафиг.

Поскольку у нас база данных PostgreSQL, то мы можем воспользоваться одной из его фич - постгрес может кавычить текст любой последовательностью типа $чтоНибудь$мой текст$чтоНибудь$.

Исходный запрос тогда может выглядеть примерно так:
SELECT class, speciality, balls FROM students WHERE stud_name=$boo$Robert$boo$ AND curse=$boo$Physics$boo$;

Да, непривычно и не очень красиво, зато фиг ты туда какие управляющие символы засунешь!
Поэтому таинственная функция R() выглядит предельно просто:
function R($text) {return '$boo$'.str_replace('$boo$', '', $text).'$boo$'}

Она заменяет в переданном ей тексте все вхождения $boo$ на пустой символ, а потом добавляет $boo$ в начало и в конец текста.
nomadmoon: (Default)
Прежде чем запускать проект и звать людей регистрироваться я хотел бы осветить некоторые вопросы безопасности, которые были затронуты при написании кода сайта.

Одним из приоритетных условий при написании сайта была необходимость защиты паролей пользователей. Для этого есть как минимум 2 метода - во первых не делать дырок в коде сайта и в запросах к базе (об этом в следующем посте), а во вторых не хранить пользовательские пароли.

На первый взгляд это нелогично, но большая часть серьезных проектов именно так и делает - вместо паролей хранят солёные хэши.

Хэш (Hash) - это не название нового модного наркотика, это устойчивое односторонее математическое преобразование, превращающее пароль qwerty в слово типа HiGyttRHdfjI8&6ugJeYykUTFvi^BtOLuih. А односторонее - это значит что из этого HiGytt_и_так_далее никто ни за что (по идее) не рассчитает математически что образовано оно было из qwerty.

Однако поскольку это преобразование устойчивое, т.е. из qwerty всегда генерится HiGyttRHdfjI8&6ugJeYykUTFvi^BtOLuih, то ничего не мешает любопытным людям с избытком свободных вычислительных мощностей заранее получить хэши всех простых паролей, слов и словосочетаний. Такие словари хэшей называются "Радужными таблицами" (не спрашивайте причем здесь геи). После чего выявление простых паролей сводится к сравнению хэша вашего пароля с ранее сгенерёнными хэшами из "радужной таблицы". Злые языки поговаривают что для одного из самых известных хэш-алгоритмов - md5 - уже нагенерены хэш-таблицы хоть на чёрта лысого.

Для длинных несловарных паролей метод не пройдет, однако поскольку все мы иногда поддаёмся искушению взять пароль попроще чтобы не забыть, то перед хэшированием пароля в него добавляется соль - какой нибудь буквенный мусор символов этак на 20.

Поэтому при регистрации выполняется такой код:
$pwd = crypt($_GET['password'], '$6$rounds=5000$ygFesRgKN:pJHHEswxrtDbnTYRXQ$');
$pg_query('insert into polzovately (user_name, password) values('.R($user_name).', '.R($pwd).')');

Встроенная функция хэширования в PHP имеет прикольный синтаксис, вторым параметром передается сразу несколько указаний:
$6$ - указывает что нужно шифровать алгоритмом SHA-512
rounds=5000 - количество циклов хэширования. Чем больше тем лучше "заметены следы" вашего изначального слова и тем дольше генерировать "радужные таблицы" для подбора
ygFesRgKN:pJHHEswxrtDbnTYRXQ - собственно, соль.

В следующем посте рассмотрим что такое $$-quoting в базе данных Postgres и что скрывается за упомянутой в коде функцией R().

Можете критиковать.
nomadmoon: (Default)
Итак, мы закончили кодить базовый функционал сайта для совместного использования всякого. На самом деле закончили мы его достаточно давно, но дела как то отвлекали от этого направления. В данный момент сервер стоит под парами и готов для деплоя. Уверен, в понедельник уже всё будет работать.

Специальн подчеркну - базовый функционал. Очень базовый.

Однако давайте посмотрим на тех кто шёл и идёт в том же направлении.
http://orangeme.org - видимо, лежит, поскольку я не смог сейчас на него зайти
http://rentmania.ru - работает, но позволяет указать город только Москва (что за местечковый шовинизм, кстати, на оранжми тоже были только Питер и Москва).

В чем, на мой взгляд их проблема? Проблему оранжми я уже называл, и она вытекает из того что сам оранжми был вдохновлён couchsurfing.org - стержневой идеологией оранжми является совместное использование вещей в основном незнакомыми людьми. Что сразу относит ценность расшеренных вещей на уровень ДаруДара. Ну не будет никто шерить ценные вещи абы с кем, согласитесь.

Рентмания эту проблему наследует, хотя и сглаживает её полукоммерческим подходом. Если проводить аналогию с сайтами шеринга жилья, то рентмания вдохновлена скорее airbnb.com, она больше подходит как сайт не для шеринга, а для, собственно, классической аренды, что с одной стороны обещает некий договор между пользователями, а с другой стороны создает оверхед в виде этих самых договоров и напрочь убивает коммьюнити. На рынке коммьюнити нет. Мир бездушного чистогана, все дела.

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

Насколько я понял, сама по себе концепция совместного использования вещей вызывает у людей поддержку.
Вопрос один - а есть ли у людей, скажем так, желание и силы начать эту кристаллизацию с себя?
Вопрос два - как я уже сказал, проект сырой. Есть ли желание и силы помогать в развитии как минимум идеями, предложениями и распространением информации?
nomadmoon: (Default)
Напомню идею - у Таннера есть фреза у меня болгарка. Если мне нужна фреза я могу у него взять фрезу... Ну вы поняли... Так как в 90% случаев я хз что есть у моих друзей и у кого может быть нужный мне по сюжету предмет Х, то хорошо было бы сделать сайт где такую инфу собирать и отслеживать.

Короче набросалась для начала такая схемка взаимодействия владельца нужного итема (owner) и навремявзятельца (borrower):


Что думаете? Понятно сформулировано? Мож где косяк? Мож что добавить?

UPD Начинать лучше либо с "Запрос" либо с "Вещь у владельца"

Profile

nomadmoon: (Default)
nomadmoon

April 2017

S M T W T F S
      1
2345678
9101112131415
16171819202122
23242526272829
30      

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 23rd, 2017 02:48 pm
Powered by Dreamwidth Studios