Сессии — JS: Express
В информатике, а конкретно в сетях, сессия — это интерактивный обмен информацией, также известный как диалог между двумя или более общающимися устройствами, или между компьютером и пользователем. Сессия (cеанс) устанавливается в определённый момент времени и позже завершается.
HTTP session
Так как HTTP — это клиент-серверный протокол, HTTP сессия состоит из трёх фаз:
- Клиент устанавливает TCP соединение (или другое соединение, если не используется TCP транспорт).
- Клиент отправляет запрос и ждёт ответа.
- Сервер обрабатывает запрос и посылает ответ, в котором содержится код статуса и соответствующие данные.
Начиная с версии HTTP/1.1, после третьей фазы соединение не закрывается, так как клиенту позволяется инициировать другой запрос. То есть, вторая и третья фазы могут повторяться.
User session
Пользовательская сессия является более высокоуровневой абстракцией, чем HTTP-сессия. С помощью неё можно не только идентифицировать разных пользователей, но также хранить произвольные данные на каждого пользователя в рамках его сессии. Типичный пример — это корзина товаров в интернет-магазине. Обратите внимание на то, что для пользовательской сессии не обязательно логиниться (выполнять аутентификацию) на сайте.
Поддержка сессий обычно реализуется с помощью специальных библиотек в рамках используемого фреймворка. В задачи этих библиотек входит:
- Установка соединения, то есть отправка специальной куки, которая содержит идентификатор сессии. Имя этой куки фиксированно и задаётся на этапе старта приложения.
- Сохранение и извлечение данных из сессии. Этот пункт сильно зависит от используемого фреймворка. В случае Express предоставляется специальный объект req.session , в который можно записывать необходимую информацию и читать её в следующих запросах. Отдельный интерес представляет хранилище данных сессии. Это можно делать в памяти, прямо в куках (в зашифрованном виде), или в различных серверных хранилищах начиная от файлов, заканчивая базами данных.
- Завершение сессии.
import session from 'express-session'; app.use(session( resave: false, saveUninitialized: false, >));
У библиотеки express-session очень много параметров, влияющих на работу сессии, и большое количество дополнений, позволяющих использовать различные хранилища. За подробностями обращайтесь к официальной документации.
К счастью, использовать сессии гораздо проще, чем их настраивать.
app.get('/increment', (req, res) => req.session.counter = req.session.counter || 0; req.session.counter += 1; >);
В примере выше в сессии инициализируется свойство counter значением 0 , а затем, при каждом обновлении страницы, счётчик увеличивается на единицу. Это будет происходить для каждого браузера независимо, потому что кука устанавливается в браузер, и браузер является «пользователем».
Для удаления сессии нужно вызывать асинхронный метод destroy .
req.session.destroy((err) => // cannot access session here >)
Аутентификация
Аутентификация это процедура проверки подлинности, например:
- Проверка подлинности пользователя путём сравнения введённого им пароля с паролем, сохранённым в базе данных пользователей;
- Подтверждение подлинности электронного письма путём проверки цифровой подписи письма по открытому ключу отправителя;
- Проверка контрольной суммы файла на соответствие сумме, заявленной автором этого файла.
Аутентификацию не следует путать с авторизацией (процедурой предоставления субъекту определённых прав) и идентификацией (процедурой распознавания субъекта по его идентификатору).
Вот как может выглядеть процесс аутентификации в Express:
app.post('/session', (req, res) => // . if (user.passwordDigest === encrypt(password)) req.session.userId = user.id; // . > // . >);
При совпадении паролей в сессию устанавливается идентификатор пользователя под ключом, который потом будет использоваться для проверки, аутентифицирован ли пользователь.
Обратите внимание на то, что в примере выше используется не сам пароль, а его хешированная версия. С точки зрения безопасности ни в коем случае нельзя хранить пароли в открытом виде. Поэтому при создании пользователя пароль специальным образом хешируется, и в хранилище уже сохраняется этот хеш. Во время процедуры аутентификации пароль, вводимый пользователем, хешируется тем же способом, что и при регистрации, а затем происходит сравнение хешей.
// encrypt.js import crypto from 'crypto'; export default text => const hash = crypto.createHmac('sha512', 'salt'); hash.update(text);
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях:
Тестируйте API, как профессионал Часть 1

Процесс автоматического тестирования и проверки функциональности программного интерфейса приложения (API) известен как автоматизация API. Она помогает убедиться, что API функционирует так, как задумано, и сокращает время и усилия, затрачиваемые на ручное тестирование.
Автоматизация API реализуется с помощью программных инструментов, которые отправляют запросы к API, анализируют ответы и сравнивают их с ожидаемыми результатами. Целью автоматизации API является повышение надежности и последовательности процесса тестирования, что позволяет экономить время и ресурсы.
Что такое REST API?
REST API расшифровывается как Representational State Transfer API (передача состояния представления API), что представляет собой архитектуру, основанную на веб-стандартах для создания веб-сервисов. Это распространенный способ взаимодействия между клиентами и серверами через интернет.
REST API используют HTTP-запросы для управления данными, чтобы POST (создать), PUT (обновить), GET (читать) и DELETE (удалять). Автоматизация API позволяет эффективно и тщательно тестировать REST API. Это реализуется за счет нескольких вызовов API и проверки ответов, что помогает выявить и устранить ошибки и проблемы на ранних стадиях процесса разработки.
Пример REST API
Предположим, у вас есть сайт, на котором размещена информация о книгах, и вы хотите, чтобы другие приложения могли получать эту информацию. Для этого вы можете создать REST API.
Вот как это работает:
Эндпоинт: Клиентское приложение создает запрос для определенного URL, так называемого эндпоинта, который представляет собой коллекцию книг. Например: «https://www.example.com/api/books«.
Методы HTTP: Клиент использует один из следующих методов HTTP для выполнения запроса:
- GET: Получение информации о книге или коллекции книг.
- POST: Добавление новой книги в коллекцию.
- PUT: Обновление информации о книге.
- DELETE: Удаление книги из коллекции.
Response (ответ): Сервер отвечает данными в определенном формате, например, JSON, которые клиент может использовать для получения информации о книгах. Например, клиент может сделать GET-запрос на «https://www.example.com/api/books«, чтобы получить список всех книг в коллекции. В ответ сервер получит полезную нагрузку в формате JSON, содержащую информацию о каждой книге, например, ее название, имя автора и номер ISBN.
Этот пример показывает, как REST API обеспечивает стандартный, программный способ взаимодействия клиентских приложений с данными сайта о книгах.
Cypress для автоматизации API
Cypress — это основанный на JavaScript фреймворк для тестирования веб-приложений. Он позволяет проводить сквозное тестирование пользовательского интерфейса и API вашего приложения. Это делает его отличным инструментом для автоматизации API.
Вот пример того, как использовать Cypress для тестирования API:
- Установите Cypress: npm install cypress —save-dev
- Создайте тестовые файлы для методов GET, POST, PUT и DELETE с cypress/e2e/cypress_api_tc.cy.js
Метод GET
Давайте посмотрим, как работают методы GET для получения данных о пользователе.
it("GET API testing Using Cypress API Plugin", () => < cy.request("GET", "https://reqres.in/api/users?page=2").should((response) =>< expect(response.status).to.eq(200); >); >);
Метод POST
Вот как работают методы POST для добавления данных о пользователе.
it("POST API testing Using Cypress API Plugin", () => < cy.request("POST", "https://reqres.in/api/users", < name: "morpheus", job: "leader", >).should((response) => < expect(response.status).to.eq(201); >); >);
Метод PUT
Давайте посмотрим, как работают методы PUT для обновления данных пользователя.
it("PUT API testing Using Flip Plugin", () => < cy.request("PUT", "https://reqres.in/api/users/2", < name: "QAAutomationLabs", job: "QA Automation Engg", >).should((response) => < expect(response.status).to.eq(200); >); >);
Метод DELETE
Давайте посмотрим, как работают методы DELETE для удаления данных пользователя.
it("DELETE API testing Using Cypress API Plugin", () => < cy.request("DELETE", "https://reqres.in/api/users/2").should((response) =>< expect(response.status).to.eq(204); >); >);
В этом примере функция cy.request() используется для отправки запроса к конечной точке. Ответ от API сохраняется в переменной response и затем может быть использован для написания утверждений с помощью Chai.js .
Результаты выполнения тестовых примеров
Вот отчет о тестах из нашего примера:

Завершить статью хочу приглашением на бесплатный вебинар, в рамках которого разберём основы тестирования API и реализуем тестирование API с помощью тестового фреймворка vitest (работает на vite).
No more tedious sample data creation, we’ve got it covered.
Real responses
Develop with real response codes. GET, POST, PUT & DELETE supported.
Always-on
24/7 free access in your development phases. Go nuts.
A hosted REST-API ready to respond to your AJAX requests.
Give it a try
- List users
- Single user
- Single user not found
- List
- Single
- Single not found
- Create
- Update
- Update
- Delete
- Register — successful
- Register — unsuccessful
- Login — successful
- Login — unsuccessful
- Delayed response
It’s all in the details
- Hosted on Heroku Which means 99.99% Uptime SLA.
All you need is the base URL, and you’re away:
Getting started
Check out the Swagger doc:
If you, for example, want to create a fake user:
For which the response to this request will be.
You can see that the API has sent us back whatever user details we sent it, plus an id & createdAt key for our use.
If you’ve already got your own application entities, ie. «products», you can send them in the endpoint URL, like so:
var xhr = new XMLHttpRequest(); xhr.open(«GET», «https://reqres.in/api/products/3», true); xhr.onload = function()< console.log(xhr.responseText); >; xhr.send();
It would be impossible for Reqres to know your application data, so the API will respond from a sample set of Pantone colour data
It’s entirely possible to get sample data into your interface in seconds!
Still don’t really get it.
- Reqres is a real API Reqres simulates real application scenarios. If you want to test a user authentication system, Reqres will respond to a successful login/register request with a token for you to identify a sample user, or with a 403 forbidden response to an unsuccessful login/registration attempt.
Peace of mind
It might seem pretty weird to be sending your data to a 3rd party API, but I can assure you, Reqres does not store any of your data at all. Once you send it to us, we just send it straight back. and then it’s gone!
Support
ReqRes serves nearly half a billion requests each month, and is provided free-of-charge.
To keep ReqRes free, contributions towards running costs are appreciated!
Selecting either option will redirect you to a hosted Stripe Checkout page to complete payment.
Advertising
Do you want to advertise your jobs/tools/software/cats through Reqres to millions of developers every week? Click for more info [pdf] on the ads. Contact for pricing and questions.
Маршруты — JS: Express
Любое приложение на Express состоит минимум из трёх элементов:
- Создание объекта приложения;
- Определение обработчиков маршрутов;
- Запуск приложения на определённом порту.
import Express from 'express'; const app = new Express(); app.get('/', (req, res) => res.send('Hello World!'); >); app.listen(3000, () => console.log('Example app listening on port 3000!'); >);
С первым и последним пунктом всё более-менее понятно, а вот обработчики — это уже интересно. Напомню, что микрофреймворки строятся по схеме: http verb + path + callback . В случае Express глагол определяется функцией, которая вызывается на объекте app . Например если мы хотим определить маршрут GET / , то для этого необходимо вызывать функцию get и первым параметром передать в неё строку / . Таким же образом нужно поступать для любого другого маршрута. Вот список глаголов, которые нас будут интересовать в процессе этого курса:
// И - Идемпотентный app.head // И app.get // И app.post app.delete // И // Полное обновление app.put // И // Частичное обновление app.patch
Семантика http подразумевает, что глаголы get, delete, head и put, являются идемпотентными. Это должно обеспечиваться программистом, который реализует обработчики.
Динамические маршруты
Самая главная и мощная функциональность системы роутинга — это работа с динамическими маршрутами.
"userId": "34", "id": "8989" >
app.get('/users/:userId/books/:id', (req, res) => const userId, id > = req.params; >);
Для динамических частей используется заполнитель :name , который состоит из двоеточия и произвольного имени. Express производит сопоставление актуального запроса со всеми шаблонами в порядке определения и выполняет соответствующие обработчики. Все динамические части маршрута попадают в объект req.params .
Кроме этого, Express позволяет использовать регулярные выражения прямо в шаблоне:
// abcd, abxcd, abRANDOMcd, ab123cd app.get('/ab*cd', (req, res) => res.send('ab*cd'); >);
Честно говоря, за свой многолетний опыт я не припомню ситуацию, когда мне это могло понадобиться. Всегда, если у вас есть возможность управлять урлами, можно сделать хороший вариант на одних плейсхолдерах (заполнителях), без прямого использования регулярных выражений.
Именованные маршруты
В приложении есть различные роуты. Например, у авторизации может стоять роут /signup . Когда мы отдаем с сервера HTML, то этот адрес мы прописываем дважды:
Про такое решение обычно говорят «хардкодить ссылки» или «магические строки». Если по какой-то причине мы решим переименовать этот роут, например, в /register , то нам надо поменять его и в роутах, и в HTML. В реальных приложениях роутов много, они состоят из нескольких частей, и переименование — не такая уж редкость.
Чтобы облегчить работу с именованием роутов, можно выделить их в отдельную константу и переиспользовать ее:
Так мы сделаем именованные роуты. Теперь все адреса записаны в одном месте и их легко поменять. Весь остальной код будет использовать эти имена.
Есть другой подход в создании именованных роутеров — с помощью специальных библиотек. Например, named-routes :
import Express from 'express'; // Импортируем библиотеку import Router from 'named-routes'; const app = new Express(); // Создаем объект роутера const router = new Router(); // Подключаем в приложение router.extendExpress(app); router.registerAppHelpers(app); app.get('/admin/users/:id', 'admin.user', (req, res, next) => // . // Создаем маршрут const path = app.namedRoutes.build('admin.user', id: 2 >); // /admin/users/2 // Имя текущего маршрута будет находиться в req.route.name >);
В примере выше был создан именованный маршрут admin.user . Теперь, где-то в другом обработчике можно строить ссылки используя имя маршрута:
app.get('/users', 'users', (req, res, next) => const path = app.namedRoutes.build('admin.user', id: 2 >); // /admin/users/2 // path содержит путь с которым можно сделать что-то полезное >);
- Если удалится маршрут, то при генерации ссылки мы получим исключение, и тесты его поймают
- Если изменится маршрут, то везде будут автоматически подставлены новые адреса
Чтобы сделать именованный роутинг действительно полезным и удобным, в других языках фреймворки предоставляют готовые решения, но в Express из коробки такой возможности нет. Поэтому в упражнениях мы продолжим хардкодить ссылки, но попробовать именованный роутинг можно будет в проекте.
Request/Response
Каждый определяемый обработчик принимает на вход два параметра: req и res . В этом смысле, всё очень похоже на ситуацию с http модулем с той лишь разницей, что там подобный обработчик один, а здесь на каждый маршрут свой. Request и Response предоставляют упрощенный интерфейс. Больше нет необходимости, по крайней мере в простых случаях, пользоваться ими как eventEmitter . На каждую задачу эти объекты предоставляют метод или свойство.
// GET /users?page=3 app.get('/users', (req, res) => console.log(req.query); // res.status(200); res.send(users); // res.json(users); >);
Пройдёмся по базовым возможностям:
- req.query готовый к обработке query string , другими словами вам не придётся парсить эти параметры, они уже поступают в виде объекта;
Открыть доступ
Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно
- 130 курсов, 2000+ часов теории
- 1000 практических заданий в браузере
- 360 000 студентов
Наши выпускники работают в компаниях: