Как в Node.js узнать местоположение пользователя?
#service #gcp
В понедельник мы говорили об определение ip пользователя. По нему можно определить местоположение, т.е. страну, город, координаты. Это данные часто используются для построения бизнес-логики.
Начинающие #nodejs разработчики устанавливают geoip-lite. В результате приложение потребляет на 100мб памяти больше. Под капотом у пакета GeoLite база от MaxMind, которая будет находиться в памяти.
Продвинутые разработчики используют сторонний сервис. Например, db-ip.com или geoip2. К сожалению, такие решения нельзя назвать дешевыми.
Наиболее опытные разработчики оптимизируют затраты, и поэтому решают эту задачу в Google Cloud Platform. Один из таких разработчиков написал статью Free IP-based GeoLocation with Google Cloud Functions. В ней описано как создать функционал аналогичный db-ip.com.
В Google Cloud Platform можно настроить custom headers так, что запрос в Node.js будет иметь заголовки с нужными данными.
Аналогичный функционал дает geoip2 модуль для nginx, но он доступен только в nginx-plus.
#service #gcp
В понедельник мы говорили об определение ip пользователя. По нему можно определить местоположение, т.е. страну, город, координаты. Это данные часто используются для построения бизнес-логики.
Начинающие #nodejs разработчики устанавливают geoip-lite. В результате приложение потребляет на 100мб памяти больше. Под капотом у пакета GeoLite база от MaxMind, которая будет находиться в памяти.
Продвинутые разработчики используют сторонний сервис. Например, db-ip.com или geoip2. К сожалению, такие решения нельзя назвать дешевыми.
Наиболее опытные разработчики оптимизируют затраты, и поэтому решают эту задачу в Google Cloud Platform. Один из таких разработчиков написал статью Free IP-based GeoLocation with Google Cloud Functions. В ней описано как создать функционал аналогичный db-ip.com.
В Google Cloud Platform можно настроить custom headers так, что запрос в Node.js будет иметь заголовки с нужными данными.
Аналогичный функционал дает geoip2 модуль для nginx, но он доступен только в nginx-plus.
Как правильно написать package.json в проекте?
#package #best_practices
#Nodejs проект начинается с package.json. Давайте посмотрим как правильно его составить для коммерческого кода.
Хорошая практика использовать scoped package.
SemVer рекомендует начинать именно с 0.1.0
Чтобы случайно не опубликовать.
Поле license описывает тип Open Source лицензии.
Поля
Имя компании обладающей правом на код
Все зависимости не меняются руками. Только в посредством
Организовать порядок в файле помогает sort-package-json. Ставить его нет смысла, поэтому
#package #best_practices
#Nodejs проект начинается с package.json. Давайте посмотрим как правильно его составить для коммерческого кода.
"name": "@<scope>/<name>"Хорошая практика использовать scoped package.
"version": "0.1.0"SemVer рекомендует начинать именно с 0.1.0
"private": true,Чтобы случайно не опубликовать.
"license":""UNLICENSED"Поле license описывает тип Open Source лицензии.
Поля
"description" и "keywords" используют для поиска в публичном npm. Не указываем их."author": "Company Name",Имя компании обладающей правом на код
"scripts": { использует одинаковое именование. Единого подхода нет. Подробней"dependencies": { содержит те пакеты, которые используются в runtime, для FE – во время сборки."devDependencies": { содержит пакеты, которые необходимы для локальной разработки и CI/CD.Все зависимости не меняются руками. Только в посредством
npm install/uninstall, чтобы изменился package-lock.json.Организовать порядок в файле помогает sort-package-json. Ставить его нет смысла, поэтому
npx sort-package-json.👍1
Как вывести в браузер сколько времени обрабатывался запрос на сервере?
#package #browser
Сегодня посмотрим, как можно узнать:
- Как быстро браузер получил ответ?
- А сколько запрос обрабатывался на сервере?
Chrome показывает Server-Timing заголовки. Для этого:
1️⃣Открываем исследуемый ресурс и консоль разработчика.
2️⃣Переходим во вкладку Network.
3️⃣Выбираем нужный запрос.
4️⃣Переходим во вкладку Timing.
5️⃣Смотрим результат.
Есть уже готовый пакет server-timing. Меня он сильно выручил в ситуации, когда было не ясно тормозит #nodejs или load-balancer.
#package #browser
Сегодня посмотрим, как можно узнать:
- Как быстро браузер получил ответ?
- А сколько запрос обрабатывался на сервере?
Chrome показывает Server-Timing заголовки. Для этого:
1️⃣Открываем исследуемый ресурс и консоль разработчика.
2️⃣Переходим во вкладку Network.
3️⃣Выбираем нужный запрос.
4️⃣Переходим во вкладку Timing.
5️⃣Смотрим результат.
Есть уже готовый пакет server-timing. Меня он сильно выручил в ситуации, когда было не ясно тормозит #nodejs или load-balancer.
Как определить не используемые зависимости?
#package #cli
На картинке популярный мем про
Проверьте свой проект. Вдруг в
#package #cli
На картинке популярный мем про
node_modules. Одной из причин раздутия данной папки являются неиспользуемые зависимости. Для облегчения их нахождения существует пакет depcheck. Устанавливать его в приложения не нужно, достаточно запустить npx depcheck . Данная команда покажет неиспользуемые и забытые зависимости. Работает как с javascript, так и с typescript. Верить результатам на 100% не стоит, особенно, если вы используете в коде магию🪄🎩.Проверьте свой проект. Вдруг в
package.json пора навести порядок.👍1
Как тестировать Dockerfile?
#package #docker
При анализе проектов я часто вижу, что нет проверки Dockerfile. Так на одном из проектов выяснилось, что сборка Docker image сломана два с половиной месяца.
Поэтому CI должен проверять, что:
➡️ Docker image собирается
➡️ Docker container стартует
➡️ health-check отдает успешный ответ
Если на проекте существуют e2e тесты, то #nodejs необходимо запускать как и в продакшене – как контейнер. Для этого отлично подходит пакет testcontainers. Он позволяет работать с Docker контекстом из кода. Вот пример из документации:
#package #docker
При анализе проектов я часто вижу, что нет проверки Dockerfile. Так на одном из проектов выяснилось, что сборка Docker image сломана два с половиной месяца.
Поэтому CI должен проверять, что:
➡️ Docker image собирается
➡️ Docker container стартует
➡️ health-check отдает успешный ответ
Если на проекте существуют e2e тесты, то #nodejs необходимо запускать как и в продакшене – как контейнер. Для этого отлично подходит пакет testcontainers. Он позволяет работать с Docker контекстом из кода. Вот пример из документации:
const path = require("path");const { GenericContainer } = require("testcontainers");const buildContext = path.resolve(__dirname, "dir-containing-dockerfile");const container = await GenericContainer.fromDockerfile(buildContext) .withBuildArg("ARG_KEY", "ARG_VALUE") .build();const startedContainer = await container .withExposedPorts(8080) .start();Что такое timing attack (атака по времени)?
#security #package
TL;DR Не используйте сравнение строк через
В веб-разработке мы часто не задумываемся об классической атаке на систему через анализ времени ответа. Исследование 2009 года показывает, что злоумышленник может измерять события с точностью 15–100ms в Интернете и с точностью 0.1ms в локальной сети.
Пример кода уязвимого к данной атаке:
Такое сравнение обрывается на первом же различном символе, поэтому можно по времени ответа подбирать ответ.
Безопасное по времени сравнение выглядит так:
Его можно использовать из пакета secure-compare.
Мне доводилось участвовать в спорах, где оппоненты говорили, что тут нет риска, так как задержка на запрос в базу данных и/или latency ответа не дадут злоумышленнику достаточно информации. Аргументы здравые. Вместо того, чтобы с ними спорить я задаю вопросы:
- есть ли в драйвере кэш запросов? Как он работает?
- Откуда злоумышленник проводить атаку из внешней или внутренней сети?
- Насколько большие затраты делать безопасное сравнение в сравнение с закрываемыми рисками?
#security #package
TL;DR Не используйте сравнение строк через
=== при проверке равенства секретов или токенов. Используйте безопасные сравнение с фиксированным временем – secure-compareВ веб-разработке мы часто не задумываемся об классической атаке на систему через анализ времени ответа. Исследование 2009 года показывает, что злоумышленник может измерять события с точностью 15–100ms в Интернете и с точностью 0.1ms в локальной сети.
Пример кода уязвимого к данной атаке:
function isAuthenticated(user, token) { var correctToken = FetchUserTokenFromDB(user); return token === correctToken;}Такое сравнение обрывается на первом же различном символе, поэтому можно по времени ответа подбирать ответ.
Безопасное по времени сравнение выглядит так:
let mismatch = 0;for (var i = 0; i < a.length; ++i) { mismatch |= (a.charCodeAt(i) ^ b.charCodeAt(i));}return mismatch;Его можно использовать из пакета secure-compare.
Мне доводилось участвовать в спорах, где оппоненты говорили, что тут нет риска, так как задержка на запрос в базу данных и/или latency ответа не дадут злоумышленнику достаточно информации. Аргументы здравые. Вместо того, чтобы с ними спорить я задаю вопросы:
- есть ли в драйвере кэш запросов? Как он работает?
- Откуда злоумышленник проводить атаку из внешней или внутренней сети?
- Насколько большие затраты делать безопасное сравнение в сравнение с закрываемыми рисками?
npm
npm: secure-compare
Securely compare two strings, copied from cryptiles. Latest version: 3.0.1, last published: 10 years ago. Start using secure-compare in your project by running `npm i secure-compare`. There are 79 other projects in the npm registry using secure-compare.
Что такое JSONPath?
#package #graphql
Работать с JSON в JavaScript крайне просто. Это подталкивает #nodejs разработчиков отдавать раздутые объекты из API. Упростить работу с такими объектами позволяет JSONPath. У него есть предшественик – Xpath, аналог для XML.
В синтаксисе всего десяток операторов. Чтобы их лучше понять, рекомендую перейти на JSONPath Online Evaluator и протестить разные выражения. Собственно вот синтаксис:
Базовые операторы – интуитивно понятны
Продвинутые операторы
Скриптовые операторы –
На уровне кода JSONPath полезен во время мутаций сложных JSON структур. Для этого используется одноименный пакет jsonpath. JSONPath встроен в Insomnia, API клиент для работы с GraphQL и REST. Поэтому многие QA выбирают его вместо Postman.
#package #graphql
Работать с JSON в JavaScript крайне просто. Это подталкивает #nodejs разработчиков отдавать раздутые объекты из API. Упростить работу с такими объектами позволяет JSONPath. У него есть предшественик – Xpath, аналог для XML.
В синтаксисе всего десяток операторов. Чтобы их лучше понять, рекомендую перейти на JSONPath Online Evaluator и протестить разные выражения. Собственно вот синтаксис:
Базовые операторы – интуитивно понятны
$ – корневой элемент@ – текущий элемент. или [] – дочерний элемент* – все элементыПродвинутые операторы
.. – так называемый рекурсивный спуск. Выбирает дочерние элементы на всех уровнях.[,] – union оператор[start:end:step] – slice операторСкриптовые операторы –
?() и () зависят от конкретного языка и библиотеки для работы с JSONPath.На уровне кода JSONPath полезен во время мутаций сложных JSON структур. Для этого используется одноименный пакет jsonpath. JSONPath встроен в Insomnia, API клиент для работы с GraphQL и REST. Поэтому многие QA выбирают его вместо Postman.
Как и зачем обновить aws-sdk с v2 на v3?
#package #aws
Два месяца назад я рассказывал как Как уменьшить потребление памяти во время TypeScript компиляции? Там я привел в качестве примера изменения импортов из
Вторая версия по-прежнему поддерживается, но переходить на третью уже пора. Вот причины:
➡️ модульная архитектура, т.е. один пакет для работы с одним сервисом. Можно не следить за правильностью import-ов как в примере.
➡️ TypeScript-first поддержка
➡️ короче Stack Trace для ошибок
➡️ оплата технической инфляции раньше ее превращения в тех.долг
Перед обновлением можно рекомендую глянуть workshop v2->v3 для самостоятельного прохождения от AWS.
#package #aws
Два месяца назад я рассказывал как Как уменьшить потребление памяти во время TypeScript компиляции? Там я привел в качестве примера изменения импортов из
aws-sdk. Этот пакет является второй версией AWS JS SDK. Я упустил выход третей версии в декабре прошлого года. Третья версия состоит из scoped packages с префиксом @aws-sdk, например @aws-sdk/client-s3.Вторая версия по-прежнему поддерживается, но переходить на третью уже пора. Вот причины:
➡️ модульная архитектура, т.е. один пакет для работы с одним сервисом. Можно не следить за правильностью import-ов как в примере.
➡️ TypeScript-first поддержка
➡️ короче Stack Trace для ошибок
➡️ оплата технической инфляции раньше ее превращения в тех.долг
Перед обновлением можно рекомендую глянуть workshop v2->v3 для самостоятельного прохождения от AWS.
Как автоматизировать 2FA?
#package #security
Данный рецепт не о том, как реализовать в своем приложение 2FA (Two-factor authentication). Для этого существуют готовые сервисы, о которых я рассказывал на React fwdays’21. Сегодня кейс из сотрудничества с QA автоматизаторами.
Для проверки приложения необходимо произвести логин пользователя. Это происходит через gmail. Переодически gmail говорит необходима дополнительная проверка – неизвестное устройство. Варианты решения отправка смс или отправка емейл не подходят, так как требуют дождаться этих смс/емейлов, способа их получения, парсинга и т.п.
В данном кейсе правильно использовать google authenticator. Данный 2FA способ виден, только если вы добавили номер телефона. В момент настройке будет показан QR code, который содержит текст вида:
#package #security
Данный рецепт не о том, как реализовать в своем приложение 2FA (Two-factor authentication). Для этого существуют готовые сервисы, о которых я рассказывал на React fwdays’21. Сегодня кейс из сотрудничества с QA автоматизаторами.
Для проверки приложения необходимо произвести логин пользователя. Это происходит через gmail. Переодически gmail говорит необходима дополнительная проверка – неизвестное устройство. Варианты решения отправка смс или отправка емейл не подходят, так как требуют дождаться этих смс/емейлов, способа их получения, парсинга и т.п.
В данном кейсе правильно использовать google authenticator. Данный 2FA способ виден, только если вы добавили номер телефона. В момент настройке будет показан QR code, который содержит текст вида:
otpauth://totp/Google:<EMAIL>?secret=<SECRET>&issuer=Google
Для того, чтобы генерировать token валидные 30 секунд вам достаточно знания secret. В этом поможет пакет otplib. Пакет позволяет генерировать и проверять не только для authenticator, но One Time Passwords, но как я уже говорил, для этого лучше использовать готовые решения.oclif.io – Open CLI Framework
#package
Вчера на Voice Chat Алексей озвучил своей виденье, что правильная организация кода должна позволять сделать из web приложения CLI утилиту. Как правило CLI утилиты написаны на Python (например AWS, GCP). Но есть примеры и на #nodejs: heroku, salesforce, twilio. Они все написаны на фреймворке oclif. У него отличная документация, возможность сразу делать упаковку в исполняемый файл под нужную операционку, публикация на S3, поддержка typescript и отличное комьюнити. Однозначный выбор для тех.стэка в проект, которому необходима CLI утилита.
#package
Вчера на Voice Chat Алексей озвучил своей виденье, что правильная организация кода должна позволять сделать из web приложения CLI утилиту. Как правило CLI утилиты написаны на Python (например AWS, GCP). Но есть примеры и на #nodejs: heroku, salesforce, twilio. Они все написаны на фреймворке oclif. У него отличная документация, возможность сразу делать упаковку в исполняемый файл под нужную операционку, публикация на S3, поддержка typescript и отличное комьюнити. Однозначный выбор для тех.стэка в проект, которому необходима CLI утилита.
👍9🔥5💩2
Что такое Fetch Event Source?
#package #architecture
На канале был рецепт Что такое Race Condition на клиенте? В нем я рекомендовал использовать Server Sent Events. Это однонаправленный протокол от сервера к клиенту. Является отличной альтеранативой websocket-ам, которые являются двунаправленным протоколом.
На сервере все достаточно просто. Например, в Nest.js есть хорошая документация – server-sent-events. На клиенте все не так просто – у нативного браузерного
#package #architecture
На канале был рецепт Что такое Race Condition на клиенте? В нем я рекомендовал использовать Server Sent Events. Это однонаправленный протокол от сервера к клиенту. Является отличной альтеранативой websocket-ам, которые являются двунаправленным протоколом.
На сервере все достаточно просто. Например, в Nest.js есть хорошая документация – server-sent-events. На клиенте все не так просто – у нативного браузерного
EventSource API есть ряд ограничений: нельзя передавать custom headers, только Get. Правильной альтернативой является пакет @microsoft/fetch-event-source. Он одновременно обладает всеми фишками fetch и Server Sent Events. Рекомендую к использованию и сам протокол SSE, и клиентский пакет от microsoft. Кто знает, вдруг эту реализацию сделают встроенной в браузерные API.👍12
Які npm пакети варто встановити глобально?
#list #package
Сьогодні розповім, які пакети в мене встановлені глобально. Я їх використовую як CLI утиліти.
- ngrok/localtunnel робить вашу програму доступною в Internet
- jscpd знаходить дублікати коду. Автор Андрій Кучеренко веде @mathrandomcommunity
- cost-of-modules показує розмір пакетів, що використовуються. Дозволяє швидко пояснити, чому в Dockerfile після
- sort-package-json сортує package.json до канонічного вигляду
- depcheck знаходить не використовувані або не оголошені в package.json залежності
- browser-run/bcat виводить результат роботу іншої CLI команди у браузер
- license-checker показує які open source ліцензії у пакетів в ваших залежностях
Перевірити ваш список:
#list #package
Сьогодні розповім, які пакети в мене встановлені глобально. Я їх використовую як CLI утиліти.
- ngrok/localtunnel робить вашу програму доступною в Internet
- jscpd знаходить дублікати коду. Автор Андрій Кучеренко веде @mathrandomcommunity
- cost-of-modules показує розмір пакетів, що використовуються. Дозволяє швидко пояснити, чому в Dockerfile після
npm run build необхідно робити npm prune --production.- sort-package-json сортує package.json до канонічного вигляду
- depcheck знаходить не використовувані або не оголошені в package.json залежності
- browser-run/bcat виводить результат роботу іншої CLI команди у браузер
- license-checker показує які open source ліцензії у пакетів в ваших залежностях
Перевірити ваш список:
npm list -g. А що і навіщо використовуєте ви?👍46❤2😱1💩1
Як протестувати routeHandler (api endpoint)?
#testing #package
Якщо вам не подобається писати типи, то доводиться писати тести. Сьогоднішній рецепт про них.
Route handler це функція, яка використовується обробки запитів, які надходять до сервера. У Nest.js це один із методів контролера з відповідними декораторами. У Express ця функція, яка приймає два параметри: об'єкт запиту (request) та об'єкт відповіді (response), та виконує необхідні дії для обробки запиту. Наприклад у цьому коді стрілочна функція є routeHandler-м:
Способи тестування:
1️⃣ Unit testing, тобто без підняття http серверу. Так тестувати недоцільно, за винятком serverless functions. До функції передаються Req/Res моки. Щоб уникнути проблем з типізацією та прискорити створення моків, використовується node-mocks-http.
2️⃣ Integration Testing, тобто з підняттям http серверу у тестах. Ще може називатися White Box Integration Testing. Часто використовується supertest. Саме так найчастіше тестують Nest.js apps.
3️⃣ End to end testing, тобто з підняттям http серверу до запуску тестів або у global beforeAll. Ще може називатися Black Box Integration Testing, Contract testing, etc. Також може використовувати supertest, але краще використовувати newman чи просто axios.
Ще існує end to end user testing. У цих тестах перевіряється користувальницький досвід і їх пишуть QA automation.
#testing #package
Якщо вам не подобається писати типи, то доводиться писати тести. Сьогоднішній рецепт про них.
Route handler це функція, яка використовується обробки запитів, які надходять до сервера. У Nest.js це один із методів контролера з відповідними декораторами. У Express ця функція, яка приймає два параметри: об'єкт запиту (request) та об'єкт відповіді (response), та виконує необхідні дії для обробки запиту. Наприклад у цьому коді стрілочна функція є routeHandler-м:
app.get('/', (req, res) => { res.send('hello world')})Способи тестування:
1️⃣ Unit testing, тобто без підняття http серверу. Так тестувати недоцільно, за винятком serverless functions. До функції передаються Req/Res моки. Щоб уникнути проблем з типізацією та прискорити створення моків, використовується node-mocks-http.
2️⃣ Integration Testing, тобто з підняттям http серверу у тестах. Ще може називатися White Box Integration Testing. Часто використовується supertest. Саме так найчастіше тестують Nest.js apps.
3️⃣ End to end testing, тобто з підняттям http серверу до запуску тестів або у global beforeAll. Ще може називатися Black Box Integration Testing, Contract testing, etc. Також може використовувати supertest, але краще використовувати newman чи просто axios.
Ще існує end to end user testing. У цих тестах перевіряється користувальницький досвід і їх пишуть QA automation.
👍25