• Сервис поиска изображений по описанию вместо ajax.googleapis?

    Taraflex
    @Taraflex
    Ищу работу. Контакты в профиле.
    из десктопного приложения

    Почему бы просто не парсить выдачу гугла? Если в один поток парсить, то не должны заблочить.
    Ответ написан
    2 комментария
  • Как правильно написать авторизацию/аутентификацию?

    @enibeniraba
    Очень сильно упрощенно, без ООП и паттернов):
    Авторизация:
    session_start();
    if (!empty($_SESSION['user_id']))
    	die('Вы уже авторизованы');
    	
    $user = get_user_by_login($_POST['login']);
    if (!$user)
    	die('Пользователь не найден');
    	
    if ($_POST['pass'] !== $user['pass'])
    	die('Неверный пароль');
    
    $_SESSION['user_id'] = $user['id'];
    die('Привет, '.$user['login']);

    При этом в куки пользователя запишется session_id, а в сессию user_id.

    Проверка:
    session_start();
    if (empty($_SESSION['user_id']))
    	die('Нет прав');
    
    $user = get_user_by_id($_SESSION['user_id']);
    if (!$user || !$user['active'])
    {
    	unset($_SESSION['user_id']);
    	die('Нет прав');
    }


    Выход:
    session_start();
    unset($_SESSION['user_id']);


    Если нужен доступ только с одного устройства (последнего, с которого был вход), то храним на сервере последнюю сессию пользователя и при каждом запросе:
    if ($user['session_id'] !== session_id())
    {
    	unset($_SESSION['user_id']);
    	die('Нет прав');
    }


    Если с нескольких, то делать ничего не нужно.

    При oauth авторизации через внешние сервисы в сессии и куках будет все то же самое.
    В бд добавятся 2 поля auth_provider и auth_provider_id.
    В auth_provider у тебя будет vk или fb или google... в auth_provider_id - id пользователя в vk, fb...
    Когда юзер нажимает кнопку войти через vk, ты его редиректишь на контакт. Там он что-то делает. Потом контакт его редиректит к тебе с ?code=request_code.
    Ты используя code делаешь запрос к api контакта на получение access_token.
    Получив access_token, делаешь запрос к api на получение инфы о пользователе. В этой инфе должен быть какой-нибудь уникальный id (auth_provider_id).
    Если у тебя нет пользователя с таким auth_provider_id для провайдера vk, то создаешь его либо без логина, либо генерируешь что-нибудь, без пароля.
    Если пользователь был создан или он был до этого, помещаешь в сессию user.id и считаешь пользователя авторизованным.

    PS:
    По каждой строчке ответа есть нюансы, но думаю общая картина такая.
    Естественно лучше написать класс для пользователя, чтобы использовать что-то вроде:
    $user->is_auth();
    $user->auth_by_id($user_id);
    $user->unauth();
    Ответ написан
    13 комментариев
  • Как правильно написать авторизацию/аутентификацию?

    dasha_programmist
    @dasha_programmist
    ex Software Engineer at Reddit TS/React/GraphQL/Go
    Есть два варианта хранения данных об авторизованном пользователе:
    1) В куки (так по умолчанию используется в асп.нет): необходимые данные (claims) шифруются machineKey и отдаются пользователю в http-only куках, таким образом при каждом запросе на сервер они присылаются, расшифровываются и далее можно проверить в необходимых местах.
    плюсы: полностью stateless, нет надобности обращаться к БД
    минусы: при необходимости "выбить" сессию со стороны сервера нужно поднимать более сложную логику и хранить флаги в промежуточном хранилище (проверять что если для такого-то пользователя требуется завершить, то такие действия, иначе другие);
    2) Ключ сессии: после успешной аутентификации авторизуем пользователя и claims храним на сервере в быстрой памяти или БД (key-value), где ключ - ключ сессии, значение - любые данные.
    плюсы: есть полный контроль состоянием авторизации (как и возможность завершить сессию со стороны сервера, так и сменить пользователю роль(или другие параметры) "на лету")
    минусы: организация доп. прослойки - кэша или хранение в БД (медленно), при перезапуске/падении сервиса сессии клиентам потребуется перелогиниться.

    1
    1.1 В куки писать или ключ сессии или шифрованные данные о пользователе, сессия - абстрактное понятие (это пара: ключ и данные), ключ должен быть защищенным, т.е. трудным к копированию (хотя бы зрительно трудно запомнить), уникальным (чтобы не возникло коллизий: двум разным пользователям выдался один и тот же ключ, т.е. это не должна быть хэш-функция от логина-пароля или IP или чего-то неуникального).
    1.2 В асп.нет существуют атрибуты авторизации (в которых можно расставлять проверки на требование таковой, роль, конкретный пользователь), в общем смысле логика такова: поступил запрос на сервер, далее нужно посмотреть к какому ресурсу идёт обращение (защищенному или свободному), если ресурс защищен, то проверить куки (ключ сессии или шифрованные данные), расшифровать/получить данные о сессии из кэша и предпринять решение: пускаем или не пускаем (отдаём 401/403 или отдаем 200/404/...).
    1.3 Завести на сервере (в кэше или БД) словарь , при алгоритме проверки сессии добавить условие проверки на наличие записи в словаре.
    1.4 С нескольких - словаря не нужно.

    2
    2.1 Даже если пользователь входит через ВК всё равно нужно отдавать свои ключи сессий/шифрованные данные, а вот внутри данных уже хранить access_token от вк-шной сессии, так очень маленькая вероятность, что токен ВК утечет, а если утек ключ сессии, то действия будут ограничены только функционалом сайта.
    2.2 После расшифровки куки или данных по ключу сессии делать доп запрос на сервер ВК с токеном, который сохранился при аутентификации (access_token), запрос простой, например получить имя пользователя, если ВК выдал что токен просрочен или ошибку, то сессию закрывать или куки с данными обнулять.
    Ответ написан
    3 комментария
  • Как использовать токены для аутентификации в API?

    bigton
    @bigton
    Web-программист
    Как сделал я.

    От классических сессий при работе через API отказался.

    1. Для авторизации пользователь вводит логинпароль, устройство отправляет их по https на account/auth
    2. account/auth выдает token (token_id:token_val) и secret
    3. все дальнейшие запросы устройство отправляет по http указывая token и подписывая запросы с помощью secret

    Как работает.

    Сервер получает запрос, видит что пришел token, разбивает его через двоеточие на input_id и input_val. Выбирает из базы токен с пришедшим input_id, получает из базы значение token_val и secret. Сравнивает input_val и token_val. Если в базе нашелся токен с нужным id и значения val равны, пришло время проверить достоверность запроса.

    Клиент помимо токена передал sign (подпись), которую сформировал так (например) secret+api_path+query_param. На стороне сервера вам известно api_path и api_param, а secret выбрали из базы. Хешировать подпись принято через hmac().

    Помимо токена и подписи можно передавать time и так же класть его в sign, и на стороне сервера отсекать запросы запросы которым больше 60 сек.

    Таким образом.

    Если кто то слушает ваш канал, он не сможет подделывать запросы (а значит компроментировать), и из-за проверки времени жизни запроса не сможет вечно получать данные по однажды перехваченного запроса.

    А в базе токены можете хранить пока клиент сам не запросит их уничтожения и сохранить время последного обращения через токен, и удалять токены которые не использовались более 60 дн.
    Ответ написан
    9 комментариев
  • Как вы относитесь к идее денежного поощрения за ответы?

    @MoonMaster
    Программист и этим все сказано
    Считаю эту идею не нужной. Если я вижу вопрос и знаю на него ответ, то почему я не должен на него ответить и помочь человеку? Согласен есть вопросы, которые на мой взгляд кажется глупыми (можно минут 5 потратить и найти ответ в интернете). Но существуют и довольно интересные вопросы с "подводными" камнями.
    Если я ответил на вопрос и он оказался решением, то я просто рад, что кому то помог. Тем более существует большая вероятность, что если я задам вопрос и мне обязательно помогут.
    Ответ написан
    5 комментариев
  • В чем разница между --save-dev и --save?

    k12th
    @k12th
    console.log(`You're pulling my leg, right?`);
    devDependencies — пакеты, которые нужны для разработки. Всякие галпы-гранты и плагины к ним обычно подпадают в эту категорию.
    dependencies — пакеты, от которых ваш пакет зависит непосредственно: как правило — библиотеки.
    Ставятся они все в node_modules.
    Тут подробнее: https://toster.ru/answer?answer_id=559717#comments...

    Если кто-то делает npm install вашему пакету, то npm подсосет те пакеты, которые указаны у него в dependencies, но не в devDependencies.
    Если сделать npm install внутри папки, в которой есть package.json, то установятся и те, и другие.
    Ответ написан
    3 комментария
  • Что такое Less и Sass?

    Fesor
    @Fesor
    Full-stack developer (Symfony, Angular)
    Лень двигатель прогресса. Хороший пример - принцип DRY - Don't repeat yourself. Я весьма подозреваю что вы стараетесь соблюдать этот принцип когда делаете макеты или чем вы там занимаетесь. Так же я весьма уверен что вы хотя бы пытались чуть автоматизировать рутину своей повседневной работы. Так же у вас могли быть ситуации когда вы переиспользовали какие-то элементы. Мало ли.

    Так вот... CSS это тупая таблица стилей. Селектор и стили, ничего сверх умного тут придумать нельзя. Лет 5-10 назад было довольно модно держать один мегажирный CSS файл на 10К+ строк и радоваться жизни внося все больше изменений и т.д. Соответственно даже если вы соблюдаете всякие правила модульной верстки и все такое, у вас возникает несколько проблем:
    • организация стилей, то есть держать все в одном файле не удобно особенно когда проект длится годами
    • Дублирование стилей и селекторов. По мере развития проекта появляются какие-то снипиты которые можно реюзать. Так же у вас может появиться масса однообразных селекторов отличающихся лишь немного. При модульных подходах вложенности редко имеет место быть но все же имеет. Но не будем забывать что большинство фигачит селекторы просто так. В итоге если мы переместили блок или переименовали класс какого-то блока нужно отредактировать еще массу селекторов.
    • Привязка размеров и параметров к другим стилям, например у вас в стилях задана ширина блока, от нее зависят другие параметры, отступы для других блоков и т.д. Да, в css3 появился calc для этого но это было относительно недавно и только с недавних пор можно почти без опаски использовать эту штуку.
    • Таблицы стилей, как и HTML ориентированы на удобный разбор этого добра машиной, но не человеком. Человек же существо ленивое и как-то вот лень лишний раз скобку поставить или точку с запятой. Просто лень.


    Есть так же хорошее правило, или идея если хотите.... Если код можно сгенерить - его лучше сгенерить. То есть для решения всех выше перечисленных проблем придумали препроцессоры. Они как бы были и раньше всех этих scss/less/stylus но как-то не решали всех проблем и т.д. Что в итоге было предложено (перечисляю в том же порядке что и в списке выше).

    • У CSS есть такая штука как @ import. Но не очень круто импортировать сотню стилей в продакшене. Стоит сделать так что бы все стили были склеены при сборке проекта. Эта идея в итоге развилась и если разработчик использует это дело правильно, можно зайти в любой файл со стилями и увидеть список всего от чего зависят эти стили. Какие стили подключаются и т.д. Причем один файл с зависимостями может быть подключен в нескольких файлах а препроцессор сам разберется как и куда все вставлять сгенерив максимально оптимизированный по структуре файл. А разработчик получил четкую структуру файлов и возможность быстро найти где что и от чего зависит.
    • С селекторами проблему предложили решить наиболее логичным вариантом. Если у нас есть вложенные селекторы, то имеет смысл определять их внутри блока этого селектора. Это существенно упрощает поддержку стилей. Так же для управления снипитами и прочим добавили миксины - эдакие параметризованные или нет функции которые выплевывают шматок CSS. До появления штук вроде autoprefixer это был единственный способ писать поддерживаемые стили, использовать плюшки CSS3 и вообще новые плюшки и не сойти с ума от префиксов. Префиксы это только пример, там могут быть самые разные штуки позволяющие грамотно производить реюз стилей
    • Проблему зависимостей значений стилей друг от друга решили... собственно самым очевидным способом - переменные. Это удобно, легко поддерживать и в умелых руках это мощный инструмент. Нужно поменять базовые цвета - не нужно лазить по 100500 блоков и править значения руками, можно поправить переменные и все будет хорошо.
    • Насколько я помню SCSS/LESS не стремились решить эту проблему. Какие-то решения образовывались сами собой с течением времени. В плане минимализма и выразительности пожалуй сейчас самая крутая штука это stylus.


    Что в итоге произошло. В один прекрасный момент какие-то там рубисты придумали SCSS (они вообще не любят все что не в стиле ruby в плане минимализма и выразительности). Затем чуваки подумали и сказали, SCSS это круто но почему-то они используют синтаксис знакомый именно Ruby разработчикам а не обычные для CSS конструкции. В итоге реализовали LESS, причем его уже реализовали на javascript, что с наличием node.js позволило это все добро еще на одной платформе собирать. А так как под эту платформу и так плодили препроцессоры оно удачно вписалось.

    Далее уже шли какие-то модификации дальнейшие, вроде того же Stylus, где синтаксис упростили просто до нельзя.

    Личное мнение. На сегодняшний день я не вижу смысла использовать чистый CSS хоть на малых хоть на больших проектах. Вот вообще никакого.
    Ответ написан
    3 комментария
  • Как сделать скриншот страницы полностью?

    PafNutY
    @PafNutY
    Люблю кодить в своё удовольствие
    Я давно для себя нашел отличную программу FastStone screenCapture именно из-за необходимости снятия скриншота с прокруткой. Она даже простенькое видео может снимать.
    Ответ написан
    3 комментария
  • Какие впечатления от Phalcon по сравнению с Symfony / Yii?

    deadbyelpy
    @deadbyelpy
    веб-шмеб
    Все собираюсь написать про это статью, да никак.
    если кратко имхо то: Phalcon лучше чем Symfony, который лучше чем Yii
    какие критериии отбора? Symfony имеет больший порог входа чем Phalcon, Yii же имеет порог входа еще меньше, но он отстает по архитектуре "внутри"
    Phalcon имеет Volt (шаблонизатор), у SF - Twig, Yii - ничего (но никто не мешает ставить туда Twig)
    У Ph,SF есть вменяемый DI, а Yii это Yii->app()
    SF поставляется с ACL, Yii - RBAC + ACL, Phalcon - ACL.
    Ph, SF2 (Doctrine) есть AR, у Yii же еще есть и DAO
    Ph на шаред хостинге не развернешь, но кто делает проекты для шаред хостингов на SF2? На Yii знаю т.к. достаточно быстро можно развернуть бложик.
    Больше написать просто неуспеваю, напоследок. делать сложные приложения на Phalcon уже можно, он готов к проду, он проще чем SF2 и удобнее, при этом архитектура у него продуманная как и у SF2
    Продвинул идею Phalcon в компании где работаю, его с радостью встретили и с радостью пользуются для сложных, enterprise проектов.
    все конечно только исходя из моего опыта работы с ними. не навязываю никому свое мнение
    Ответ написан
    6 комментариев
  • Почему меняется яркость экрана ноутбука?

    @belkov_k_v
    .Данную проблему решил отключением флажка "vari-bright" - данный параметр оптимизирует яркость экрана ноутбука и снижает его энергопотребление. Правой кнопкой мыши кликаешь по рабочему столу далее жмешь свойства графики. Далее Питание/PowerPlay там убираешь флажок с "включить vari-bright" и все ок ))
    Ответ написан
    1 комментарий
  • Как организовать защиту от парсинга сайта?

    @starosta6123
    1. Сайт изначально предназначен для публикации, то есть он открыт.
    2. Если вы не хотите чтобы информация была открыта, не публикуйте.

    Из 1 пункта следует, что нет достаточных средств для защиты от парсеров.
    Вопрос только в том, на сколько вы готовы и можете усложнить жизнь для парсеров.
    А нужно ли это? Может вы - "неуловимый Джо"?
    Все что может прочитать и распознать человек (а ведь именно для людей и делается сайт?) может быть воспроизведено. В части, где парсинг может быть автоматизирован, он будет автоматизирован.
    Сейчас существуют мощные парсеры Яндекса и Гугла. Если они ваш сайт не смогут разобрать, то и в индексе его не будет, значит полезная информация не дойдет до конечного пользователя.
    А тот, кто захочет, ее скопирует, если информация очень нужна. Если даже вы представите в виде мозаики из картинок и кусков, даже если зашифруете, но информация на экране должна все равно быть читабельной, а значит простой принтскрин и распознавание в FineReader будет быстрее, чем вы напишите защиту от него...

    Бросьте это занятие!

    Не существует защиты созданной человеком, которую не возможно сломать, вопрос времени...
    Единственный путь, это шифрование с выдачей ключа клиенту. Но клиент - человек не надежен, и информация уплывет, вопрос цены!

    И еще раз бросьте это!

    Я тоже когда-то думал об этом, но ни к чему не пришел. Всякая защита усложняет систему и увеличивает количество ошибок. Пользователь быстрее уйдет с вашего сайта, только потому что из-за ошибки в скрипте полезные данные не получит.

    Последний совет: бросьте это!

    Единственное что может вам помочь, это не раскрывать полностью всю информацию о предмете, или разделить на несколько частей, но при этом не должно быть неудобства для посетителя. К примеру, скройте "количество зубцов в шестеренке", любую ключевую информацию, без которой "самолет не взлетит".

    А если хотите поиграться, то пришла в голову идея: перемешивание по определенному алгоритму текста, который потом восстанавливается, применение стилей для скрытия "фальшивых" слов или фраз. Например, задать стиль, который скрывает каждое второе предложение или слово. Но к сожалению, это ломается на ура! Но доставит радости для взломщиков :-)

    Извините, за столь большой сумбур!

    1. Динамические запросы. Ну доставят какую-то головную боль для взломщика, но это не так сложно, как кажется.

    2. Верстка. Не знаю про бан от поисковиков, но это тоже ломается. Просто убираете теги и все. Просто в парсер добавляется "умный" фильтр. Можно конечно где-то картинку заменить фоном, или часть текста картинкой, но и на это можно сделать разборщик.

    3. Блокировка по IP не прокатит, так как могут пострадать реальные люди, достаточно применять динамический IP.

    А вообще, если хотите спастись от простых парсеров, то комплекс мер может помочь. Так же могу натолкнуть на идею, того, что парсеры обычно очень активны, и по количеству запросов с одного IP, по USER_AGENT, и другим меткам, а так же по отсутствию javascript, по обработке тега <МЕТА> redirekt.info/article/redirekt-na-html-s-zaderzhko... (отложенный редирект) и другим признакам. Можно запихнуть скрытую картинку (style="display: none"), большинство парсеров ее могут дернуть (зависит от настроек).

    В общем, можно поставить задачу в другом ключе: "Расстановка ловушек для парсеров". То есть ловить на том, чего обычные люди и браузеры делать не будут. Например, заполнять "скрытое поле пароль". Удачные ловушки дадут вам возможность выявить подставных, но лучше делать несколько проверок, а то можно и реального пользователя забанить. А я бы не стал банить, а сливал бы немного или частично измененную инфу. Эта инфа может стать маркером для выявления того, кто действительно желает с вас "слить".

    Все, удачи!
    Ответ написан
    4 комментария
  • Лучший CSS фреймворк для Flat дизайну

    VitalySorokin
    @VitalySorokin
    тружусь во благо «ТМ»
    Не стоит! Верстай сам!
    Ответ написан
    Комментировать
  • Удобный компилятор LESS-файла в CSS код?

    Я на время разработки собираю less на стороне клиента. И только после запуска проекта уже компилирую его в css и подключаю
    Ответ написан
    Комментировать
  • Javascript-шаблонизатор (client-side)

    @1nd1go
    Использую $.nano (по-моему я его немного подкрутил):

                $.nano = function(template, data) {
                    return template.replace(/\{([\w\.]*)\}/g, function (str, key) {
                        var keys = key.split("."), value = data[keys.shift()];
                        $.each(keys, function () { value = value[this]; });
                        return (value === null || value === undefined) ? "" : ($.isArray(value) ? value.join('') : value);
                    });
                };
    


        <script id="results-tmpl" type="text/html">
                <p>Correct: {correct}</p>
                <p>Wrong: {wrong}</p>
            </div>
        </script>
    


    $("#container").html($.nano($("#results-tmpl"), {correct : "1"}));
    
    Ответ написан
    2 комментария
  • В каких браузерах LESS не умеет компилироваться в CSS джаваскриптом на стороне клиента?

    banzalik
    @banzalik
    На оф сайте есть ссылка на русскую документацию
    lesscss.ru/
    LESS может использоваться как на стороне клиента (IE 6+, Webkit, Firefox)
    Ответ написан
    Комментировать
  • Как повысить безопасность https при использовании самоподписанного ssl-сертификата?

    okazymyrov
    @okazymyrov
    >> Где выкладывать сертификат для скачивания, чтобы можно было избежать его подмены? Нужно, чтобы там был https и там было сложно подменить файл.

    В Сhrom-e можно просмотреть сертификат и экспортировать его. Я думаю, что достаточно будет написать мануал, как его скачать к себе на компьютер и добавить в доверенные.
    Ответ написан
    Комментировать