Разработка веб приложений. #2 - Backend, Express.

Первая статья — здесь.

Для начала — большое спасибо всем за то что приняли мою первую статью, было приятно. Ну а теперь вторая… :)

Frontend разработка штука конечно занятная и очень интересная, да и платят вкусно. Однако чем были хороши WP и MODx, так это готовой backend частью, на базе которой можно было на коленке собрать сайт почти любого типа. Мне очень не хотелось возвращаться к использованию CMS (про CMS будет в одной из следующих статей) и я решил внимательно изучить тренды backend индустрии для веб-приложений.

Т.к. я сменил PHP на JS, прыгать обратно на PHP оказалось больно. Причем факапился на обычном синтаксисе, наверное дело привычки, но неудобно. Тропинка в итоге привела меня к Node.js.

Важно! Я буду приводить статистические данные за 2019 год на которые я в свое время опирался и дополню их свежими данными за 2020 и 2021 год. Все это лишь статистика, которая не являлась и не является ключевым фактором, а лишь дополнительным источником информации.
Почему JS и Node?
Для начала отвечу на свой же вопрос, почему нода, почему JS? Нам разработчикам (не важно фронт или бек), крайне важно следить за трендами. Конечно если вы постоянно в теме разработки, общаетесь с коллегами, читаете статьи или ездите/смотрите на всякие митапы, то так или иначе вы будете в курсе тенденций нашей индустрии.

Но для меня в меру моей неопытности в беке, было все не так очевидно. И я начал исследовать. Для начала скажу — что выбор у меня был не особо большой, либо все таки PHP, либо JS. Почему так? Да очень просто, оба этих языка я в той или иной мере уже знал и на работе / фрилансе мне нужно было решать задачи и зарабатывать деньги. Начинать изучать что-то с нуля конечно круто (говорят даже важно практиковать как можно больше языков программирования), но деньги были важным критерием.

Для начала по JS. За последние несколько лет, этот язык очень очень и очень сильно подтянули, причем подтянули настолько сильно, что многие современные браузеры за ним не поспевают. Отсюда например у babel еженедельно 36 миллионов скачиваний на NPM…

Давайте посмотрим на статистику популярности языков программирования.

* 2019
* 2020
* 2021

Занятно да? Хочу отметить рост TypeScript, т.к. о нем я напишу в следующей статье. Что касается JS — ничего удивительного, это по сути единственный клиентский язык программирования, которым мы все чудно нагружаем браузеры пользователей. :) Но все таки главенство JS является довольно важным фактором.

Теперь посмотрим что там по ноде.

* 2019
* 2020
* 2021

Тут крайне важно обратить внимание, что стековерфлоу переместили ноду из раздела фреймворки и библиотеки, в раздел языков программирования. Решение очень спорное, ведь нода это не язык программирования. Ну да ладно, из-за смены категории, нода очевидно потеряла лидерство и свой процент, однако даже в новой и очень конкурентной категории, утерла нос тому же PHP, Golang, Ruby и т.д.

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

И вот начитавшись статей, насмотревшись статистик и посмотрев некоторое количество интервью и выступлений на ютуб, я пошел на HH. Сравнил количество вакансий и если грубо, то у PHP в 2 раза больше вакансий чем у ноды. Примерно такое я и ожидал на самом деле, всякие WP и битриксы никуда не делись, а вот в среднем 1000 вакансий по ноде меня приятно удивили.

Решил изучать серверный JS!

Обучение
Ну конечно я очень быстро пришел к express. Наверное многие из вас слышали про него, фреймворк на ноде для веб-разработки. Принял решение изучать его. Почему? Ну потому что как бы самый популярный и для входа в мир ноды довольно простой.

Однако прежде чем использовать фреймворк, я решил приобрести на юдеми курс по ноде и экспрессу, в котором преподователь показывает на простом примере как на ноде написать свой сайт с SSR за пару часов. Если что — вот тут весь код сайта. Невероятно мало кода, а бек и шаблонизация уже готовы, магия…

По сути, это единственный курс который я прошел в качестве обучения, все остальное — документация и гугл.

Express.js
Прежде чем начинать что-то делать на экспрессе, я объясню что я вообще хотел от бека. Ну конечно для начала — управление контентом сайта, а для этого в написанную мной на Vue админку надо как-то попасть, отсюда у меня родилась идея сделать модуль для сотрудников сайта (не путать с обычными юзерами).

За идею я взял архитектуру пользователей в MODx, доработал ее и принялся писать этот модуль на Express.js. Вот так например выглядит моя первая версия модуля авторизации для сотрудников, которую я написал вначале 2020 года:

async login({ body: { email, password } }, res) {
    try {
      if (validator.isEmpty(email)) {
        return res.status(422).send(
          {
            field: 'email',
            type: 'isEmpty',
            message: 'Email is empty.',
          },
        );
      }

      if (!validator.isLength(email, { min: 4, max: undefined })) {
        return res.status(422).send(
          {
            field: 'email',
            type: 'isLength',
            message: '4 characters minimum.',
          },
        );
      }

      if (!validator.isEmail(email)) {
        return res.status(422).send(
          {
            field: 'email',
            type: 'isEmail',
            message: 'This is not an email.',
          },
        );
      }

      if (validator.isEmpty(password)) {
        return res.status(422).send(
          {
            field: 'password',
            type: 'isEmpty',
            message: 'Password is empty.',
          },
        );
      }

      const normalizedEmail = validator.normalizeEmail(email);

      // Trying to login
      const staff = await Staff.findOne({ email: normalizedEmail });

      if (!staff) {
        return res.status(403).send({ message: 'Login or password in incorrect.' });
      }

      const isPasswordCorrect = bcrypt.compareSync(password, staff.password);

      if (!isPasswordCorrect) {
        return res.status(403).send({ message: 'Login or password in incorrect.' });
      }

      const accessToken = jwt.sign({
        userId: staff._id,
        email: staff.email,
      }, process.env.JWT_SECRET, { expiresIn: '5m' });

      const refreshToken = jwt.sign({
        userId: staff._id,
        email: staff.email,
      }, process.env.JWT_SECRET_REFRESH, { expiresIn: '5d' });

      const foundToken = await StaffToken.findOne({ staff: staff._id });

      if (foundToken) {
        await StaffToken.findByIdAndUpdate(foundToken._id, { token: refreshToken });
        return res.status(200).send({
          accessToken,
          refreshToken,
          id: staff._id,
          user: staff.email,
        });
      }

      const token = new StaffToken({ token: refreshToken, staff: staff._id });
      await token.save();

      return res.status(200).send({
        accessToken,
        refreshToken,
        id: staff._id,
        user: staff.email,
      });
    } catch (err) {
      return res.status(500).send({ message: 'Internal server error.' });
    }
  },

Сегодня (да и собственно вчера) это называется анти-паттерн. Так делать сегодня — это не правильно. Но полтора года назад я об этом не особо-то и знал. Я тут считай только только вник в Event Loop и осознал что такое однопоточность… Короче мой модуль был написан и готов, готовы были и endpoints которые я с радостью применил в своей админке на Vue.

И о чудо, за чуть более чем 2 недели, тратя по 2-3 часа в день, я написал свой первый модуль на express, сумел авторизоваться в админке, умел создавать, редактировать и удалять пользователей. А так же чуть позже дополнил модуль системой ролей и пермишенов.

Как видно по коду выше, авторизация работает на JWT, даже рефреш токен сделал. Но самое главное, это то, что мне безумно сильно понравилось писать модули на express. Даже в рамках моего маленького опыта и не очень красивого кода, это было приятно и очень интересно.

Мой стек на момент написания кода выше:

* Git
* Docker
* Express
* Mongo
* Vue 2 (dashboard)
* Nuxt 2 (frontend)

Вот таким вот образом, я начал свой путь в мире backend разработки на ноде, работая при этом на основной работе фулл-тайм на frontend части.

Разочарование
У меня в контактах не было ни одного знакомого, который мог бы мне хотя бы немного помочь в освоении нового инструмента, даже за вознаграждение. И это очень сильно прокачивает! Конечно есть чаты, но не всегда там тебе могут помочь, особенно когда проблему не объяснить в двух словах.

Мой backend разрастался модулями и в какой-то момент я заподозрил что-то странное. Мне вдруг начало становиться все сложнее и сложнее работать с моим проектом. Архитектура MVC которая зачастую используется в express начала показывать свою неидеальность (именно по этой причине кстати, серьезные дядьки на express уже давно использует другие архитектурные паттерны). Пытаясь разобраться почему так, я узнал что есть такой фреймворк как Nest.js.

Пробежавшись по нему я ужаснулся, TypeScript, OOP, DI и многое многое другое. Посмотрев на свой backend и узнав что я использую анти-паттерн, глубого вздохнув, я отсрочил реализацию моих модулей и решил (пока это не так больно), переходить к изучению Nest и TS.

Продолжение уже будет в следующей статье, но забегая в нее скажу — что переход на Nest стало невероятно крутым решением и я даже очень рад, что начал я именно с Express. Так же, в следующей статье я покажу во что в итоге превратился мой метод авторизации сотрудников, но уже в рамках Nest.
iWatchYouFromAfar
25 января 2022, 22:20
modx.pro
1
2 958
+20
Поблагодарить автора Отправить деньги

Комментарии: 55

Aleksandr Huz
25 января 2022, 23:15
+3
Мини-сериал! Жду след. серию))
    Александр Мельник
    26 января 2022, 09:07
    0
    У меня вопрос, философский. Как раз вчера над ним размышлял и возможно вы поможете.
    Вопрос наверное можно сформулировать так — откуда берутся стеки технологий?
    Поясню, что я имею ввиду.
    Если спросить у разработчика php какую базу данных он использует, 99 процентов ответят что mysql.
    Врядли они смогут ответить на вопрос — почему.
    Если спросить разработчика на python то ответ будет Postgress.
    Если у разработчика на node js — ответ будет Mongo.
    Хотя каждая из этих систем может работать с любой из этих баз данных.
    Хотелось бы услышать ваш опыт — работая на php вы наверняка использовали mysql, а перейдя на nodejs выбрали mongo. Почему?
    Просто потому что как в опыте с «обезьянками в запертой комнате» — здесь так принято?
    Или вы провели для себя сравнительный анализ между возможными базами и выбрали mongo как лучшую?
    Ведь mongo относится к группе nosql баз данных и чтобы работать с ней — нужно кардинально перестроить голову и мысли в ней, она очень отличается по характеру от mysql.
      iWatchYouFromAfar
      26 января 2022, 22:20
      0
      Я как и большинство долго работал с MySQL, затем на Nest я поработал с Mongo, затем переключился на PostgreSQL, а ведь есть еще GraphQL.

      Свой выбор остановил на Монге просто потому что мне с ней пока что очень удобно работать. Наверное люди с бОльшим опытом работы смогут тебе объяснить более тонкие нюансы, но все что я делал на MySQL, я спокойно реализовываю и в Монге.
        Руслан Сафин
        27 января 2022, 13:17
        0
        у монги есть серьезные проблемы на средних и больших проектах… база может развалится чуть ли не на ровном месте, там приколы с движком WiredTiger, с полной потерей данных. сейчас на работы мы используем 3 реплики базы в кластере что бы минимизировать риски (бд более 400гб)
          Павел Гвоздь
          01 февраля 2022, 07:46
          0
          Но ведь GraphQL это не БД, а язык запросов. В какую базу будут выполняться запросы, это уже решает бекенд api.
            iWatchYouFromAfar
            02 февраля 2022, 13:51
            0
            Конечно, я это и имел ввиду, SQL базы данных или noSQL или GraphQL.
        Александр Мельник
        26 января 2022, 09:28
        0
        Еще вопрос из той же серии. Простите, но просто хочу понять ход ваших мыслей.
        Вы пишите что начали использовать typescript.
        Вы реально ощутили необходимость в строгой типизации данных? Прям поняли, что неудобно работать на чистом js, возникают ошибки изза смены типа переменной?
        Или же это просто «плыву по течению» и «модно, стильно, молодежно»?
        Или к этому толкают правила компании в которой работаете?

        ps. прочел внимательнее и понял, что на изучение ts вас толкнул выбор nest.js
          Руслан Сафин
          26 января 2022, 16:58
          +2
          Если проект хоть немного больше сайта каталога, ts в разы ускоряет разработку. С ts видишь подсказки что в находится в объектах, минимизируется количество банальных ошибок (опечатки, перепутал название и т.д.)

          Пока сами не попробуете ts сложно объяснить его необходимость… Я после ts, на голом js совсем писать не хочу
            Александр Мельник
            26 января 2022, 17:13
            0
            Я понял, спасибо.
            Если вы действительно осознанно выбрали typescript а не просто следуя трендам, это приятно и похвально.

            А Руслан, простите, я думал это ответил автор заметки.
            iWatchYouFromAfar
            26 января 2022, 22:23
            +1
            Я уже начал писать следующую статью, там как раз будет TS и типизация. Я наглядно покажу что такое типизация на более сложном примере, чем объявления типа переменной.
            Роман
            27 января 2022, 17:14
            0
            Жду продолжение, статья вдохновляет. Спасибо, что делитесь такими подробностями.
              Futuris
              10 мая 2022, 16:59
              0
              А эти ваши сложности работы с проектами на express касаются каких-то больших и сложных проектов?
              Я вот собрался подучить JS и познакомиться с JS-фреймворками и JS-бэкэндом. Остановился как раз на связке Nuxt JS + Express + MongoDB. Я не программист, и на мой совсем неэкспертный взгляд это показалось наиболее доступной для начального освоения связкой. И кстати Express раньше ставился «из коробки» при установке Nuxt, а теперь этого почему-то нет.
                Василий Наумкин
                11 мая 2022, 17:06
                0
                И кстати Express раньше ставился «из коробки» при установке Nuxt, а теперь этого почему-то нет.
                Потому что не нужно — у Nuxt есть свой собственный сервер, лучше его и использовать.
                  Futuris
                  11 мая 2022, 17:14
                  0
                  Имеется в виду, что у Nuxt собственный сервер, который можно использовать для бэкэнда? И ко всему этому можно «прикрутить» базу данных?
                    Василий Наумкин
                    11 мая 2022, 17:23
                    0
                    Да, свой полноценный сервер со многими фишками — v3.nuxtjs.org/guide/concepts/server-engine/

                    Работа с БД не зависит от вида сервера — он просто будет выполнять ваш код.
                      Futuris
                      11 мая 2022, 17:26
                      0
                      Спасибо! Буду читать документацию.
                  iWatchYouFromAfar
                  12 мая 2022, 10:52
                  +1
                  Отвечаю на вопрос про Express. Изучать его и написать на нем пару проектов — маст хев, т.к. это что-то вроде флагмана в мире бекенда на JS, плюс тот же Nest из коробки использует под капотом именно Express. Потыкав пальцем в Express, уже сам поймешь куда тебе двигаться дальше.

                  Неидеальности Express заключается минимум в его архитектуре, которая с ростом проекта становится сложночитаемой и сложноподдерживаемой. Ты это сам поймешь когда попробуешь сделать нечто большее чем просто блог.
                    Futuris
                    13 мая 2022, 10:39
                    0
                    Буду разбираться с этим, конечно. Но я сразу Nuxt 3 разбираю, а там нет Express из коробки, и нужно разобраться как его туда интегрировать, либо использовать дефолтный Nitro.
                  Александр Мельник
                  12 мая 2022, 07:31
                  0
                  Господа, раз уж здесь обсуждаются технологии из мира javascript, то хочу услышать ваше мнение и опыт использования jwt токенов как инструмента авторизации?
                  Изучаю эту технологию и честно говоря, на мой взгляд, это очень небезопасная система.
                  Плюс вижу, что совершенно каждый разработчик реализует логику работу с jwt по своему, кто то даже хранит их (access token) в базе, хотя по моему это полностью противоречит идее самого токена. Зачем тогда сигнатура в токене, если хранить в базе ассоциацию между пользователем и токеном, это по сути получается механизм сессий с хранением в базе.
                  Какую бы документацию не читал, везде встречаю фразу типа — даже если у вас украдут токен, то он позволит пользоваться сервисом не долго. Не говоря уже о том, что большинство разработчиков не ставят время жизни в 10 минут, а ставят 12 часов а то и больше, но даже 10 минут хватит, чтобы не спеша и попивая кофе выкачать например всю базу с клиентами. Ничего себе система авторизации и безопасности).

                  Но это мои и пока теоретические мнения. А есть у кого то реальный и положительный опыт использования токенов именно как инструмента аутентификации? Как применяете его вы? Где храните токены на клиенте? В localstorage? Разбирались ли глубоко

                  Собственно, почему я, человек далекий (надеюсь что это временно ) от nodejs и стеков типа MEAN, решил вообще изучить jwt. Изобретаю механизм межсерверной аутентификации. Нужно сделать, чтобы человек авторизовавшись в одном сервисе (домене и сервере), перейдя на другой сервис (домен и сервер) сохранил свою аутентификацию и был уже авторизован. Инструмент сессий для этого мало подходит, ну разве что с хранением сессии в общей базе данных, к которой будут иметь доступ все сервисы… В общем буду рад вашим идеям, я то найду и изобрету такой механизм, но чужой опыт — всегда бесценен.
                    Сергей Шлоков
                    12 мая 2022, 09:06
                    +1
                    Изучаю эту технологию и честно говоря, на мой взгляд, это очень небезопасная система.
                    Web — это вообще небезопасная сфера.

                    Какую бы документацию не читал, везде встречаю фразу типа — даже если у вас украдут токен, то он позволит пользоваться сервисом не долго.
                    А если у тебя украдут авторизационную куку?

                    Не говоря уже о том, что большинство разработчиков не ставят время жизни в 10 минут, а ставят 12 часов а то и больше
                    Честно говоря, сомневаюсь в твоей оценке. Уверен, есть такие разработчики, но их количество резко сокращается с увеличением опыта. Особенно, когда они узнают про refresh token.

                    кто то даже хранит их (access token) в базе
                    Наверно это те же «спецы».

                    Изобретаю механизм межсерверной аутентификации.
                    Пополняешь список велосипедостроителей? Есть уже готовые стандарты — OAuth2 и OpenID Connect. Первый — это протокол авторизации. Второй — это надстройка над первым для аутентификации. Он позволяет использовать единый логин (SSO) для сервисов. Для всех языков есть библиотеки.
                    В id токене ты можешь хранить информацию о пользователе (его id, email или телефон). По нему ты можешь получить пользователя из БД, которого в крайнем случае ты можешь заблокировать. Это один из вариантов.
                    Кроме того, авторизационный сервер хранит access_token для клиента.

                    В комментарии всё не опишешь. Но в инете много информации по этому вопросу. Странно задавать его здесь.
                      Александр Мельник
                      12 мая 2022, 09:41
                      0
                      спасибо.
                      Но в инете много информации по этому вопросу. Странно задавать его здесь.
                      Но мы ведь с вами как раз и в инете) На сайте который представляет из себя форум, на котором обсуждаются технологии веб разработки и на котором находятся много умных людей, поэтому задать вопрос здесь — мне кажется очень разумным.
                      Я вот например впервые в жизни слышу про OpenID Connect. И ничего подобного по запросу — межсерверная авторизация мне не попадалось, а вы раз — и подсказали.
                      Вы правы, я жутко люблю изобретать велосипеды, а не использовать чьи то готовые решения. Понимаю, что в 2022 году это неправильный подход, но ничего поделать не могу. Для меня программирование это прежде всего изобретательство и наслаждение от поиска решения, а когда — установи вот эту библиотеку и скопипасти со стековерфлов такой то код — то это наоборот боль. Но это мои тараканы)
                      iWatchYouFromAfar
                      12 мая 2022, 11:04
                      0
                      А что по твоему идеально-безопасный механизм аутентификации пользователя? Тот же twitch.tv использует очень похожу на JWT аутентификацию, записывая и перезаписывая в localStorage разные данные.

                      JWT это технология, которая дает достаточно стабильный механизм аутентификации. А его доработку и безопасность уже дорабатывай сам. Программа минимум — делать refresh token.

                      Ну и если за твой сервис возьмуться специалисты, которые занимаются взломом за деньги, то готовься к сложностям.

                      Еще советую посмотреть видео Ильи Климова про JWT аутентификацию.
                        Александр Мельник
                        12 мая 2022, 11:12
                        0
                        спасибо, я конечно же смотрел видео Ильи.
                        И он как раз тоже рассказывает о том, что jwt это небезопасный инструмент, тот случай когда технология стала популярной не за заслуги, а вопреки недостаткам.
                        Но мои знания теоретические, я еще нигде не использовал jwt в серьезных проектах.
                        По крайней мере украть куку через js гораздо сложнее (есть способы сделать ее недоступной) а вот доступ к
                        localstorage закрыть нельзя.
                          Александр Мельник
                          12 мая 2022, 11:22
                          0
                          плюс расскажите пожалуйста как вы решаете проблему «первого запроса».
                          Ведь токен нужно передать на сервер при первом запросе.
                          — пользователь запускает браузер
                          — вводит адрес
                          — браузер получает ip сервера
                          — в браузере в локалстораже лежит access токен
                          Каким образом он будет передан в первом запросе, чтобы пользователь сразу был авторизован?
                          Как этот вопрос решаете вы?
                            Сергей Шлоков
                            12 мая 2022, 16:49
                            +1
                            JWT обычно используют для API. Если тебе нужно использовать его на сайте, то пихай его в куки. Можно использовать пакет jwtSession.
                        Александр Мельник
                        12 мая 2022, 09:30
                        0
                        nextjs, nestjs,nuxtjs, vuejs — голова кругом идет. Причем я так понимаю что vue это фреймворк языка js, а nuxtjs это уже фреймворк фреймворка vue.
                        я часто вижу видео по разработки чего либо на nodejs, всегда все разработчики запускают какой либо из веб серверов у себя локально, на каком то доступном порту и разрабатывают. Но я никогда не видел, как это деплоится на продакшен сервер и самое главное, как это там работает?
                        Поделитесь пожалуйста информацией.
                        — вы что, на продакшене тоже не используете nginx? Кто именно слушает 80 порт и передает запросы приложению?
                        — как вообще решается вопрос с размещением нескольких сайтов на одном сервере? Если у апача есть свои вирутальные хосты, у nginx есть понятие server{} и эта настройка тоже содержит hostname и позволяет создать большое количество сайтов на одном сервере, то ничего подобного у того же express я не вижу. Максимум что можно сделать, это запустить несколько «серверов express» на разных портах, но это ведь не сделает их доступными в интернет. Все равно ведь нужно иметь nginx который будет принимать запросы на 80 порту, получать домен и проксировать запрос в зависимости от домена на express. Или я ошибаюсь?
                        — если все таки nginx действительно не используется, а сервера на продакшине представляют собой запущенный express или nuxt nitro, который сразу слушает 80 порт, то неужели эти программы действительно способны тягаться в безопасности и стабильности с гигантами и давно зарекомендовашими себя apache или nginx? Это сервисы проверенные временем и пользователями, а что такое nuxtjs nitro? Он буквально возник недавно, в документации написано что всего 9 месяцев назад его начали разрабатывать. Что мы можем знать о безопасности этого продукта?
                          Futuris
                          12 мая 2022, 11:29
                          0
                          Но я никогда не видел, как это деплоится на продакшен сервер и самое главное, как это там работает?
                          Если даже у вас это вызывает вопросы, представьте как у меня крыша кипит.)) Все эти
                          npm run dev
                          , и тоже думаю — а кто-бы показал, как это все на реальном хостинге и конкретном домене работает.))
                            Александр Мельник
                            12 мая 2022, 11:45
                            0
                            Ну вот давайте попросим вместе автора этого поста поделиться такой информацией.
                            Как работает экспрес, уроки по ноде и прочее — в сети миллиарды.
                            А вот то как устроен сервер, на который это размещается. Как там устроено принятие запросов, кто слушает какие порты, как организовать два домена на одном сервере и так далее — вот этого почти нет.
                              Futuris
                              12 мая 2022, 11:50
                              0
                              Было бы неплохо, конечно.
                                iWatchYouFromAfar
                                12 мая 2022, 12:36
                                0
                                Это уже тема не ноды, а настройки серверов на Nginx. Моя серия именно про работу с нодой в кач-ве бекенда (к слову, я цикл статей еще не завершил).

                                Не уверен что буду писать «how to», но могу дать очень полезный совет. Арендуй простой сервер, и попробуй развернуть там два сайта самостоятельно, инструкций по конфигурации серверов в инете масса, но ищи на английском языке лучше.

                                Запускаешь процессы ноды на разных портах, затем проксируешь их через nginx на нужный тебе порт, главное в директиве server_name указать нужный домен.

                                P.S.
                                Да и вообще, переход на JS с MODx и прочих CMS-ок дался мне не так просто, как первый сайт на том же WP или MODx. Не жди что придет кто-то и разжует тебе все, делай сам. Будет дольше, но тогда ты точно научишься и уже сам напишешь (а может и не напишешь) статью.
                                  Александр Мельник
                                  12 мая 2022, 12:52
                                  0
                                  ну тоесть nginx все таки используется на продакшене?
                                  Нет, не вопрос в том чтобы это запустить, я довольно хорошо разбираюсь в администрировании линукс серверов и смогу настроить и многодоменность и проксирование запросов.
                                  Вопрос в том что это нигде не обсуждается разрабочтками ну и плюс наверное путаницей в терминологии. Вот Василий выше написал что nuxtjs разработал свой сервер, взамен express.
                                  И у меня складывается впечатление, что именно на вот таких серверах (express, nitro) и работает все на продакшене без использования nginx, что кажется мне совершенно неверным решением.
                                    iWatchYouFromAfar
                                    12 мая 2022, 12:56
                                    0
                                    Я еще не использовал Nuxt 3 и не могу точно сказать про Nitro. Это не замена серверу Nginx, это замена серверу в среде Node.js.
                                      Futuris
                                      13 мая 2022, 10:51
                                      0
                                      Как понял из вашей дискуссии JS-фрейморвки на Апаче вообще не работают? Нужно сразу настраивать Nginx? Поэтому, наверное, и не вижу на сервере установленный Nuxt.
                                    Александр Мельник
                                    12 мая 2022, 12:55
                                    0
                                    возможно в крупных компаниях есть отдельно веб разработчики и отдельно девопс инженеры, которые деплоят это все на сервера, поэтому стандартный веб разработчик даже не задумывается как в реальности его код будет работать, ему достаточно запустить какой то локальный веб сервер, поэтому нигде в виде уроках этот момент и не рассматривается.
                                      iWatchYouFromAfar
                                      12 мая 2022, 12:57
                                      0
                                      Да почти в каждом платном и даже бесплатном, более менее нормальном уроке рассматривается деплой на продакшн.
                                        Александр Мельник
                                        12 мая 2022, 13:11
                                        0
                                        значит не то смотрю.
                                        Но в любом случае спасибо, потому что вы ответили на довольно важный в понимании работы nodejs вопрос. Можно я вкратце опишу, а вы скажите прав ли я в различиях в работе програмного обеспечения на php и nodejs
                                        — nodejs в отличии от php не умеет работать в качестве модуля веб сервера или отдельного демона в системе, которому можно передать файл с кодом и он его выполнит. Как это мы делаем в php-fpm например. передаем код на некоторый сокет на котором работает интерпретатор php
                                        — поэтому у нас в php и нет промежуточного понятия — сервер php. Ну формально он есть через команду php -S но он если и используется то только для разработки. Но nodejs может обрабатывать код только при наличии внутреннего сервера, вот почему и возникают exspress и им подобные?
                                        — любое приложение на ноде (устал переключать раскладку) которое хочет работать с http запросам, должно запустить свой собственный сервер, настроенный на какой то порт, а запросы от клиента ему будет пересылать nginx слушающий 80 порт? Отбросить из этой цепочки внутренний сервер мы не можем? Как делаем в php? Когда у нас nginx просто перенаправляет все запросы в единую точку входа?
                                          iWatchYouFromAfar
                                          12 мая 2022, 14:26
                                          0
                                          1 — Nodejs фактически и есть веб-сервер, который запускается на сервере и обрабатывает JS в код нижнего уровня. Запустив такой веб-сервер, ты можешь ему передавать файлы с кодом и он (веб-сервер), их выполнит.

                                          2 — Nodejs может исполнять код как только будет установлен в систему / на сервер. У него из коробки идет свой веб-сервер, если ты не хочешь использовать фреймворки на подобии Express. Такой веб сервер поднимается буквально в 5 строчек кода. Пример — github.com/LeCoupa/awesome-cheatsheets/blob/master/backend/node.js#L11.

                                          3 — Я не слишком глубого знаком с работой PHP, но в рамках ноды — ты запускаешь веб-сервер, который слушает некоторый порт и этот порт проксируется через Nginx на нужный (например 80). Отбросив внутренний веб-сервер Nodejs, ты останешься без веб-сервера.
                                      Futuris
                                      13 мая 2022, 10:50
                                      0
                                      но могу дать очень полезный совет. Арендуй простой сервер, и попробуй развернуть там два сайта самостоятельно
                                      Установил на свой VPS NodeJS, поставил Nuxt 3, а дальше затык и пока не разобрался как же хоть страницу приветствия Nuxt увидеть, как на локалке. Да, это конечно сложнее чем запустить первичную установку WP или MODX.
                                        Александр Мельник
                                        13 мая 2022, 12:33
                                        0
                                        я не подскажу, к сожалению. Плохо вообще понимаю что такое nuxt и зачем это существует. Очень слабо понимаю, зачем для работы js фрейворков требуется аж два одновременно работающих вебсервера — свой и nginx (пусть даже последний выполняет роль прокси сервера). Это все равно если бы мы писали программу на php, переносили ее на продакшен, так запускали локальный веб сервер php
                                        php -S localhost:8080 -t public
                                        естественно что так до нашей программы нельзя достучаться из браузера, поэтому мы запускаем еще и nginx который настраиваем на проксирование всех запросов с порта 80 на порт 8080 и оно даже будет работать, но вопрос — зачем.
                                        Но вам чтобы увидеть приветственную страницу именно так и нужно сделать. Установить nginx, настроить его дефолтный конфигурационный файл на слушанье 80 порта и тупое проксирование всех запросов на тот порт, на котором запустился ваш nuxt
                                          Futuris
                                          13 мая 2022, 13:02
                                          +1
                                          я не подскажу, к сожалению. Плохо вообще понимаю что такое nuxt и зачем это существует.
                                          Для меня, как SEO-специалиста только Nuxt, благодаря серверному рендерингу (чего нет, насколько понимаю у чистого Vue) дает возможность подойти к новому стандарту разработки на JS. Если нет серверного рендеринга (SSR) — поисковики не индексируют нормально JS-сайты, а это для меня самое важное в веб-разработке.
                                            Александр Мельник
                                            13 мая 2022, 14:08
                                            0
                                            гугл умеет хорошо индексировать без ssr, а вот яндекс, вы правы, не хочет.
                                              Futuris
                                              13 мая 2022, 14:55
                                              0
                                              в РФ никуда без Яндекса)
                                            Futuris
                                            13 мая 2022, 13:48
                                            0
                                            Попробую переключиться на nginx и настроить как вы советуете. Спасибо!
                                              Василий Наумкин
                                              13 мая 2022, 18:26
                                              +2
                                              Это все равно если бы мы писали программу на php, переносили ее на продакшен, так запускали локальный веб сервер php
                                              Вообще-то, именно так и происходит.

                                              Сам Nginx умеет отдавать только статичные файлы, а обработку php он передаёт другому процессу. Как правило, это php-fpm, который непрерывно крутится в памяти сервера. И для запуска нового сайта на хостинге этот процесс нужно перезапускать.

                                              Разница лишь в том, что сервер php запускает ваш хостер. А сервер node.js нужно запускать самому. Но это говорит лишь о неразвитости хостинга для node. Я могу себе представить с будущем хостинги для node, где всё будет настроено так же удобно, как сегодня для php.

                                              Ровно так же Nginx может отдавать обработку запроса в ruby, python, go, опять же в node.js и еще много куда. Сам Nginx этого ничего не умеет, потому что он reverse-proxy server.

                                              Для справки, Apache2 работу с php тоже сам по себе не поддерживает, он это делает через встроенный модуль mod_php, который может быть и отключен.
                                                Александр Мельник
                                                13 мая 2022, 19:29
                                                0
                                                с этим почти согласен. Ну разве что php-fpm не является серверов, это процесс демон интерпретатора php.
                                                  Александр Мельник
                                                  13 мая 2022, 19:49
                                                  0
                                                  nginx у нас это прокси сервер, nitro это веб сервер. Причем я почитал документацию, он умеет отдавать и статику тоже.
                                                  Зачем использовать nginx, почему не настроить nitro на 80 порт и слушать запросы напрямую на нем?
                                                    Василий Наумкин
                                                    14 мая 2022, 05:58
                                                    +2
                                                    Так можно сделать только если на сервере всего один сайт, который займёт 80 порт.

                                                    А если сайтов 2 или более — то нужен Nginx или Apache2, которые будут разруливать запросы.

                                                    Очевидно, что на публичных хостингах тебе просто придётся работать с одним из них.
                                              Василий Наумкин
                                              13 мая 2022, 18:30
                                              0
                                              Да, это конечно сложнее чем запустить первичную установку WP или MODX
                                              Это просто 2 разных уровня сложности и мастерства.

                                              На MODX и WP можно пилить сайты вообще без знаний, просто кликая мышкой. А Nuxt и прочее Node.js это уже для серьёзных специалистов.

                                              Придётся учиться, но оно того стоит.
                                                Александр Мельник
                                                13 мая 2022, 19:34
                                                0
                                                А Nuxt и прочее Node.js это уже для серьёзных специалистов.
                                                с этим наверное не соглашусь. Наоборот, современная разработка становится все более высокоуровневой, мы оперируем сплошными абстракциями, все дальше уходя от компьютера как железа. Программировать становится все проще, синтаксис все сахарнее. Скоро доживем до того, что программирование будет типа
                                                const site = new Site();
                                                site->getWonderfullShop('no cart please');
                                                Поэтому не соглашусь, что nodejs это для специалистов. Синтаксис там простой, библиотек море.
                                                Вот ассемблер — это для специалистов.
                                                  Василий Наумкин
                                                  13 мая 2022, 19:41
                                                  0
                                                  Да что ты говоришь.

                                                  Тут вот люди даже Hello World пока не могут вывести, а потом начнутся вопросы про реактивность, асинхронность и Vuex.

                                                  Для того, чтобы это стало простым и клёвым, нужно взойти на определённую высоту. После этого — да, оно всё просто. А вот MODX и WP наоборот кажутся очень сложными и неудобными, вот такой парадокс.

                                                  Насчёт ассемблера… Ну как покажешь веб-сайт на ассемблере, тогда и продолжим сравнения.
                                        Александр Мельник
                                        14 мая 2022, 08:49
                                        0
                                        а вот еще хотелось бы мне подискутировать на затронутую мной же тему jwt токенов.
                                        Кто скажет, почему payload не шифруется а лишь кодируется? В чем сокральный смысл использовать base64, который очень просто раскодировать и узнать данные?
                                        Как я понимаю жизненный цикл access токена:
                                        — сервер авторизации и сервер, на котором мы хотим обратиться знают один и тот же ключ, при помощи которого создана сигнатура в токене.
                                        — мы при каждом запросе мы передаем этот токен на сервер. Сервер (в каком то midleware ну или как там разработчик сделает) берет payload и кодирует тем же ключем. И сравнивает сигнатуру которую он получил с той, что пришла в токене.
                                        — если сигнатуры совпали это говорит о том, что запрос пришел от того, кто обращался на наш сервис авторизации и смог получить токен.
                                        — НО мы ничего еще не знаем о самом клиенте. Кто именно делает запрос. А если у нас есть деление на какие то роли и не каждый кто просто получил токен имеет пользоваться всем. Или же мы ведем логирование запросов и нам нужен хотя бы id пользователя. Тоесть как ни крути, там же на этапе аутентификации нужно раскодировать payload и получить исходные данные, чтобы получить например объект с перечислением ролей и определить, допустима ли тому, кто отправил запрос, операция удаления пользователей.
                                        — тоесть сам факт проверки сигнатуры не дает еще полной картины, раскодировать payload прийдется каждый раз.
                                        — и в такой схеме действительно возникает проблема. Если токен украли, то пока он «жив» вор может пользоваться им и нанести вред.

                                        Теперь собственно моя идея.
                                        — раз нам все равно на каждый запрос нужно раскодировать payload токена, то почему не включить в него информацию, которая позволит решить проблему с угоном токена. Что-то что будет служить дополнительной защитой.
                                        — к примеру ip адрес того, кто обратился на сервер авторизации и получил токен. Добавим ip в payload и на этапе аутентификации на своем сервере, сравниваем, а тот ip что пришел в токене и реальный ip который мы получаем из самого запроса — совпадают ли?
                                        — так же в случае если мы говорим про применение jwt не для общения с api, а для использования в браузере, в токен можно добавить user-agent, который даст информацию о том, с какой операционной системы и с какого браузера был получен токен. И есть еще масса уникальной информации, которую можно получить и использовать для идентификации того или иного устройства.
                                        — что это нам дает. Решение классической проблемы — угнали токен и до конца его жизни могут пользоваться. Теперь даже в случае угона токена, он не будет принят на сервере, на который мы стучимся, потому что точно не пройдет проверку ip и скорее всего не пройдет проверку user-agent.
                                        — нельзя конечно полностью утверждать, что это 100 процентная защита от угона токена, вернее от возможности его использование вором, но это уже сильно усложнит жизнь вору. Насколько я знаю, подделать ip с которого отправляешь свой запрос на какой то конкретный (а чтобы токен прошел валидацию нужен именно конкретный), не так уж и просто. Но предположим что супер хакеры умеют.
                                        — и мы возвращаемся к моему вопросу — почему payload просто кодируют, а не шифруют? Тот кто украл токен имеет прямой доступ к информации, пусть даже и не знает ключа шифрования, при помощи которого была создана сигнатура. В моей схеме, вор получив токен сразу же использует его чтобы получить доступ к нашему сервису. Не выходит, банально потому что его ip не совпадает с тем с которого он совершает запрос.
                                        — если payload только закодирован base64 вор получает с него данные и видит, что в данных содержится и ip. И начинает как то решать эту проблему и искать способ подделать свой ip на этот конкретный. Если время жизни токена невелико то и времени для поиска решения не много. Но ведь можно не дать ему и этого шанса. Не будем кодировать, будем шифровать payload. Мы уже используем один ключ, который создает сигнатуру. Можем использовать его или завести еще один. Чистые данные шифруем при помощи ключа. получаем payload. payload шифруем при помощи ключа — получаем сигнатуру. Складываем их вместе, получаем довольно безопасный токен.
                                        — теперь даже если украсть токен, то «тупое» его использование ничего не даст и дело не во времени его жизни, а в несовпадении данных из токена с реальными данными запроса. И посмотреть что лежит в payload хакер тоже не может, данные не закодированы, а зашифрованы и не имея ключа их не расшифровать.

                                        Такой подход, как мне кажется, даже позволит завести в свой системе авторизации пару приятных плюшек:
                                        — автопродление токена. Поскольку у нас теперь токен содержит дополнительные уровни защиты, то в зависимости от уровня безопасности всего проекта, можно облегчить жизнь нашим пользователем. Если токен пришел на сервер и в нем все идеально, кроме времени жизни (он уже протух), можно не отправлять пользователя на повторную авторизацию руками, а самим сделать запрос на наш сервис авторизации, передать туда данные из payload и получить новый токен. Никто ведь из людей не любит очень часто вводить пароль. Но это для проектов, чей уровень безопасности не высок.
                                        — можно вести статистику успешных и неуспешных использований токена и на основании ее изменять время жизни токена для конкретного пользователя. Если видим, что присылается токен с зашитым внутрь одним ip а запрос приходит с другого ip, то в следующий раз этому клиенты выдадим токен не на 30 минут, а на 5 минут.
                                          Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
                                          55