Форум

Методология

Инструментарий

Платформа

Сообщество

Создаем динамический БЭМ-проект

Введение

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

Цель документа — показать, как разрабатывать динамические проекты по БЭМ, используя полный стек технологий.

В документе рассмотрен процесс создания динамического приложения Social Services Search Robot (SSSR). Оно позволяет искать последние твиты и видео по ключевому слову.

При разработке проекта используется:

После прочтения вы сможете разрабатывать собственные БЭМ-проекты, ориентированные на динамические данные.

Обратите внимание, что для работы с примерами, описанными в документе, необходимо иметь базовые навыки:

  • HTML

  • CSS

  • JavaScript

  • БЭМ

Важно! В документе не рассматриваются вопросы верстки и клиентского JS.

Для работы потребуется установить:

Важно! Пользователям операционной системы Windows необходимо дополнительно установить Git Bash.

Все примеры программного кода, описанные в документе, проверены в версиях:

  • Node.js — 4.7.0.

  • npm — 4.5.0.

Примечание. npm — менеджер пакетов, входящий в состав Node.js.

Используемые обозначения

В документе приняты следующие условные обозначения:

  • folder — директория;

  • file — файл;

  • add folder — создать директорию;

  • add file — создать файл;

  • edit file — отредактировать файл.

Используемые технологии

Полный стек технологий БЭМ состоит из:

  • BEMDECL — технология для описания деклараций в БЭМ.

  • DEPS — технология для описания зависимостей в БЭМ.

  • BEMTREE — шаблонизатор преобразующий данные в BEMJSON.

  • BEMHTML — шаблонизатор преобразующий BEMJSON в HTML.

  • i-bem.js — JavaScript-фреймворк для БЭМ.

Подробнее о BEMJSON-формате входных данных.

BEMDECL

Определяет список БЭМ-сущностей, используемых на странице.

Такой список в БЭМ называется декларацией. Задача декларации — определить, что и в каком порядке подключать в сборку.

Декларации описываются в файлах с расширением .bemdecl.js.

Пример декларации из приложения Hello, World:

// Файл `desktop.bundles/index/index.bemdecl.js`
exports.blocks = [
    { name: 'root' }
];  

Как видно из примера, в файле index.bemdecl.js определен только блок root.

При использовании технологии DEPS, в декларации определяют БЭМ-сущность, с которой будет начинаться сборка проекта.

Блок root следует рассматривать как центральную «точку входа» при работе над проектом. Все остальные БЭМ-сущности попадают в сборку по зависимостям.

Пример сборки проекта по зависимостям:

root(DECL)
|
└──> root(DEPS)
     |
     └──> page(DEPS)
          |
          ├──> header(DEPS)
          |    |
          |    └──> ...
          |
          ├──> body(DEPS)
          |    |
          |    └──> ...
          |
          └──> footer(DEPS)
               |
               └──> ...

Подробнее о технологии BEMDECL.

DEPS

Определяет зависимости между БЭМ-сущностями, которые разнесены по файловой структуре проекта и не отражены в декларации.

Зависимости описываются в виде JavaScript-объекта в файлах с расширением .deps.js.

Пример зависимостей для блока root из приложения Hello, World:

// Файл `common.blocks/root/root.deps.js`
({
    shouldDeps: 'page'
})

Подробнее о технологии DEPS.

BEMTREE

Является частью шаблонизатора bem-xjst и преобразует данные в BEMJSON.

Шаблоны описываются в BEMJSON-формате в файлах с расширением .bemtree.js.

Вход и выход шаблонизатора:

BEMTREE

Подробнее о технологии BEMTREE.

BEMHTML

Является частью шаблонизатора bem-xjst и преобразует BEMJSON-описание страницы в HTML.

Шаблоны описываются в файлах с расширением .bemhtml.js.

Вход и выход шаблонизатора:

BEMHTML

Подробнее о технологии BEMHTML.

i-bem.js

Клиентский JavaScript-фреймворк для веб-разработки в рамках БЭМ-методологии.

JavaScript-код описывается в файлах с расширением .js.

Позволяет:

  • разрабатывать веб-интерфейс в терминах блоков, элементов, модификаторов;

  • описывать логику работы блока в декларативном стиле — как набор состояний;

  • легко интегрировать код JavaScript с BEMHTML-шаблонами и CSS;

  • гибко переопределять поведение библиотечных блоков.

Подробнее о технологии i-bem.js.

Приложение Hello, World

У программистов есть традиция: начинать программирование на новом языке или фреймворке с приложения Hello, World. Приложение обычно выводит слова «Hello, World» в выходной поток, демонстрируя тем самым, что оно запускается и может выполнять операции ввода/вывода.

Давайте создадим это приложение, а затем расширим его до желаемого SSSR.

Для этого понадобится локальная копия шаблонного репозитория bem-express. Копию можно сделать с помощью Git.

Примечание. Для пользователей OS X или Linux все команды выполняются в терминале. Пользователям Windows потребуется Git Bash. Убедитесь, что Git Bash запущен от имени администратора.

Шаблонный репозиторий

При решении задач по разработке динамических приложений в рамках БЭМ создан шаблонный репозиторий bem-express. Он содержит необходимый минимум конфигурационных файлов и решает целый класс задач, таких как сборка проекта, настройка линтеров, подключение библиотек и др.

В bem-express по умолчанию подключены основные БЭМ-библиотеки:

Быстрый старт

Чтобы создать приложение Hello, World, выполните следующие действия:

  • Склонируйте bem-express:

    git clone https://github.com/bem/bem-express.git sssr-project
    

    Примечание. В данном примере используется bem-express версии 2.00.

  • Перейдите в директорию проекта:

    cd sssr-project
    
  • Удалите историю версионирования исходного репозитория:

    rm -rf .git
    
  • Инициализируйте собственный Git-репозиторий:

    git init
    
  • Установите зависимости:

    npm install
    

    Примечание. Не используйте права суперпользователя root при установке npm-зависимостей.

  • Соберите проект и запустите сервер:

    npm run dev
    

    Примечание. За сборку проекта отвечает ENB.

    При запуске приложения в терминале выведится сообщение о том, что сервер выполняется на порте 3000:

    Server is listening on 3000.

    Примечание. Если порт 3000 используется другой программой, его можно переназначить. Например, на 8000:

    Способ 1. Изменение значения при запуске приложения.

    PORT=8000 npm run dev
    

    Способ 2. Изменение значения по умолчанию в файле server/config.js.

    defaultPort: 8000
    

    На компьютере запустился:

    • сервер — отвечает за обработку динамических данных;

    • nodemon — следит за изменениями в файловой структуре и перезапускает сервер;

    • chokidar — следит за изменениями в файлах директорий *.blocks/ и перестраивает структуру проекта;

    • livereload — обновляет страницу в браузере.

  • Откройте браузер и введите адрес localhost:3000.

    Должна открыться страница со следующим контентом:

    Index page content
    footer content
    

    Примечание. Если при запуске приложения в Windows, выводится уведомление от Брандмауэра:

    • Отключите опцию

      Общественные сети
      (Public Network).

    • Установите опцию

      Частные сети
      (Private Network).

    • Разрешите доступ.

  • Откройте файл server/index.js и внесите следующие изменения (см. комментарии) в код начинающегося строкой app.get('/', function(req, res):

    /**
     * Функция обрабатывает все GET-запросы с главной страницы приложения
     * @function
     * @param {object} req - Запрос.
     * @param {object} res - Ответ.
     */
    app.get('/', function(req, res) {
        var hello = 'Hello';                  // Инициализируем переменную `hello`
        var world = 'World';                  // Инициализируем переменную `world`
        render(req, res, {
            view: 'page-index',
            title: 'Main page',
            meta: {
                description: 'Page description',
                og: {
                    url: 'https://site.com',
                    siteName: 'Site name'
                }
            },
            hello: hello,                     // Передаем переменную `hello` в `this.data.hello`
            world: world                      // Передаем переменную `world` в `this.data.world`
        })
    });
    
  • Откройте файл common.blocks/page-index/page-index.bemtree.js и замените его содержимое на следующее:

    block('page-index').content()(function() {
        // Получаем данные из глобального объекта `this`
        var data = this.data;
        // Возвращаем полученные данные: `data.hello: 'Hello'`, `data.world: 'World'`
        return data.hello + ', ' + data.world;
    });
    

    После сохранения сервер автоматически перезапустится и контент страницы изменится на:

    Hello, World
    footer content
    

Приложение Hello, World готово.

Не получилось?

Если при создании приложения возникли сложности, поищите решение на форуме. Если готового ответа не нашлось, задайте вопрос экспертам.

Файловая структура

После установки всех зависимостей файловая структура приложения Hello, World должна иметь следующий вид:

sssr-project/
    .enb/                 # Конфигурационные файлы для сборщика ENB
    common.blocks/        # Базовые реализации блоков
    desktop.bundles/      # Директории бандлов проекта
    development.blocks/   # Блоки, подключаемые в процессе разработки
    node_modules/         # Установленные модули Node (пакеты)
    server/               # Директория с серверным кодом
    static/               # Корневая директория для раздачи статических файлов
    .bemhint.js           # Конфигурация линтера Bemhint
    .borschik             # Конфигурация сборщика файлов Borschik
    .eslintignore         # Исключение файлов и директорий в ESLint
    .eslintrc             # Конфигурация ESLint
    .gitignore            # Исключение файлов и директорий в Git
    .stylelintrc          # Конфигурация Stylelint
    .travis.yml           # Автоматический запуск линтеров в Continuous Integration
    nodemon.json          # Конфигурация для пакета Nodemon
    package.json          # Описание проекта для npm
    README.md             # Текстовое описание проекта

Рассмотрим подробнее некоторые основные директории:

.enb

Содержит конфигурацию сборщика ENB.

Сборка решает следующие задачи:

  • Объединяет исходные файлы, разложенные по файловой структуре проекта.

  • Подключает в проект только необходимые блоки, элементы и модификаторы.

  • Учитывает порядок подключения.

  • Обрабатывает код исходных файлов в процессе сборки (например, преобразует LESS-код в CSS-код).

Алгоритм сборки описывается в файле .enb/make.js.

Подробнее о сборке БЭМ-проектов.

common.blocks

Содержит реализации всех БЭМ-сущностей проекта.

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

common.blocks/
    body/                 # Директория блока body
    footer/               # Директория блока footer
    header/               # Директория блока header
    page/                 # Директория блока page
        _view/            # Поддиректория модификатора page_view
        page.bemtree.js   # Реализация блока page в технологии BEMTREE  
        page.deps.js      # Реализация блока page в технологии DEPS
    page-index/           # Директория блока page-index
    root/                 # Директория блока root

Перед отправкой в браузер файлы собираются и оптимизируются.

desktop.bundles

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

Одной директории бандла соответствует одна страница проекта:

desktop.bundles/
    index/                # Бандлы для страницы index
        index.bemdecl.js  # Декларация для страницы index
        index.bemhtml.js  # Бандл страницы index в технологии реализации BEMHTML
        index.bemtree.js  # Бандл страницы index в технологии реализации BEMTREE
        index.css         # Бандл страницы index в технологии реализации CSS
        index.deps.js     # Бандл страницы index в технологии реализации DEPS
        index.js          # Бандл страницы index в технологии реализации JS
        ...

Примечание. Единственным не автоматически сгенерированным файлом в директории index является файл index.bemdecl.js. Подробнее технология BEMDECL рассматривается ниже.

server

Содержит модули Node, которые прослушивают веб-запросы и генерируют страницу.

Файловая структрура директории:

server/
    config.js             # Конфигурация приложения
    index.js              # Точка входа приложения
    rebuild.js            # Пересборка приложения
    render.js             # Рендеринг HTML

Модули и их назначение:

  • index.js — модуль инициализации и запуска приложения. Подключает Express.js и различные модули, осуществляющие поддержку middleware.

  • config.js — модуль с конфигурационными данными приложения. Определяет настройку приложения по умолчанию (порт, директория для хранения статических файлов, секретный ключ сессии).

  • rebuild.js — модуль автоматической пересборки проекта. Следит за изменениями в файлах и директориях (директории: *.blocks и static), пересобирает и перезапускает проект.

  • render.js — модуль рендеринга HTML. Получает на вход BEMJSON, достраивает его необходимыми данными и генерирует HTML.

static

Содержит статические файлы, предназначенные для внешнего доступа:

static/
    favicon.ico           # Фавиконка
    index.min.css         # Символическая ссылка на desktop.bundles/index/index.min.css
    index.min.js          # Символическая ссылка на desktop.bundles/index/index.min.js

Подробнее о символических ссылках.

Приложение Social Services Search Robot

Demo

SSSR — это сервис для поиска твитов и видео, отвечающих заданному набору параметров. Параметры поиска передаются в Twitter Search API и YouTube Data API в виде HTTP-запроса методом GET. Программные интерфейсы формируют ответ в виде JSON-документа.

Цель разработки данного приложения — показать:

  • как связать воедино данные и интерфейс;

  • какие технологии используются и за что отвечают.

На базе этой инфраструктуры (приложения SSSR) можно реализовать множество динамических БЭМ-проектов для решения частных задач.

Примечание. Для разработки приложения необходимо установить некоторые модули Node.

Схема работы приложения

Схематично работу приложения можно представить следующим образом:

Chart of Social Services Search Robot

Шаг 1. Запрос

Пользователь отправляет запрос на сервер.

Шаг 2. Получение данных

Приложение обращается за данными к Twitter Search API и YouTube Data API в соответствии с полученным от пользователя запросом.

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

Шаг 3. BEMTREE-шаблонизация

Приложение передает полученные данные BEMTREE-шаблонизатору, который преобразует данные в BEMJSON.

Шаг 4. BEMHTML-шаблонизация

Приложение передает BEMJSON BEMHTML-шаблонизатору, который преобразует BEMJSON в HTML.

Шаг 5. Отправка результата пользователю

Приложение возвращает результат (HTML-страницу) пользователю.

Примечание. Обновлять можно как всю страницу целиком, так и контент нужного блока.

Используемые модули Node

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

Важно! В разделе не рассматриваются все используемые модули. Подробно с необходимым модулем можно ознакомиться на сайте npm. Здесь можно найти каталог всех модулей Node с поддержкой поиска.

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

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

Все пакеты установленные с помощью менеджера пакетов npm находятся в директории node_modules.

Подключение модулей происходит при помощи команды require. Если пакет установлен с использованием npm, указывать путь не нужно. Достаточно указать имя:

var express = require('express');

При подключении собственного локального модуля, необходимо указать к нему путь:

var someModule = require('./somefolder/somemodule');

Важной особенностью любого модуля является то, что он должен быть рассчитан на взаимодействие с Node. Для этого модуль нужно экспортировать с помощью module.exports:

module.exports = {
    // some module
};

Для работы приложения потребуются следующие модули:

Примечание. Установить необходимые модули можно одной командой:

npm install express passport passport-youtube-v3 twitter googleapis moment --save

express

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

Установка:

npm install express --save

В документации Express представлено минимальное приложение «Hello World Express». Оно демонстрирует основную последовательность действий:

var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World!')
});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!')
});

passport

Предоставляет различные стратегии аутентификации в приложениях на Node.js.

Установка:

npm install passport --save

Пример авторизации по протоколу OAuth 2.0:

var passport = require('passport'),
    OAuth2Strategy = require('passport-oauth').OAuth2Strategy;

/**
 * Функция монтирует необходимую стратегию авторизации
 * @function
 * @param {string} provider — Например, facebook, twitter, google, ...
 * @param {object} strategy — Стратегия авторизации
 */
passport.use('provider', new OAuth2Strategy({
    authorizationURL: 'https://www.provider.com/oauth2/authorize',
    tokenURL: 'https://www.provider.com/oauth2/token',
    clientID: SERVICE_APP_ID,
    clientSecret: SERVICE_APP_SECRET,
    callbackURL: 'https://www.example.com/auth/provider/callback'
}));

Примечание. OAuth 2.0 — открытый протокол авторизации, который позволяет предоставить третьей стороне ограниченный доступ к защищенным ресурсам пользователя без необходимости передавать ей (третьей стороне) логин и пароль.

passport-youtube-v3

Предоставляет механизм аутентификации на Youtube посредством аккаунта Youtube и токенов OAuth 2.0.

Установка:

npm install passport-youtube-v3 --save

Пример

var passport = require('passport'),
    YoutubeV3Strategy = require('passport-youtube-v3').Strategy;
/**
 * Функция монтирует стратегию YoutubeV3Strategy
 * @function
 * @param {object} strategy — Стратегия
 */
passport.use(new YoutubeV3Strategy({
    clientID: YOUTUBE_APP_ID,
    clientSecret: YOUTUBE_APP_SECRET,
    callbackURL: '/auth/youtube/callback',
    scope: ['https://www.googleapis.com/auth/youtube.readonly']
}, verify));

Подробнее о том как получить OAuth-токены.

twitter

Клиентская библиотека для работы с Twitter REST API.

Установка:

npm install twitter --save

Пример

var Twitter = require('twitter');
// Создаем экземпляр объекта Twitter
var client = new Twitter({
  consumer_key: '',
  consumer_secret: '',
  bearer_token: ''
});

var params = {q: 'bem'};
/**
 * Функция поиска. Ищет твиты по заданным параметрам.
 * @function
 * @param {object} params - Параметры поиска.
 * @param {function} callback - Получает найденные твиты.
 */
client.get('search/tweets', params, function(error, tweets, response) {
  if (!error) {
    console.log(tweets);
  }
});

googleapis

Клиентская библиотека для работы с Google REST API.

Установка:

npm install googleapis --save

Пример

var google = require('googleapis'),
    OAuth2 = google.auth.OAuth2;
// Создаем экземпляр объекта OAuth2
var oauth2Client = new OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);
// Устанавливаем учетные данные для исходящих вызовов
oauth2Client.setCredentials({
  access_token: 'ACCESS TOKEN HERE',
  refresh_token: 'REFRESH TOKEN HERE'
});
// Логинимся
var youtube = google.youtube({
    version: 'v3',
    auth: this.oauth2Client
});

var params = {q: 'bem'};
/**
 * Функция поиска. Ищет видео по заданным параметрам.
 * @function
 * @param {object} params - Параметры поиска.
 * @param {function} callback - Получает найденные видеоролики.
 */
youtube.search.list(params, function(error, video, response) {
  if (!error) {
    console.log(video);
  }
});

moment

JavaScript библиотека для синтаксического анализа, валидации и форматирования дат.

Установка:

npm install moment --save

Пример

var moment = require('moment');

moment().startOf('day').fromNow();             // 17 часов назад

Подготовка структуры проекта

Прежде чем начать писать код, необходимо немного изменить структуру взятого за основу приложения Hello, World.

Изменения для:

Изменения для статических файлов

static

Директория static

  • Создайте поддиректорию images.

  • Перенесите фавиконку в поддиректорию images.

Директория common.blocks

Директория server

  • Отредактируйте файл index.js.

    Измените:

    .use(favicon(path.join(staticFolder, 'favicon.ico')))
    

    На:

    .use(favicon(path.join(staticFolder, '/images/favicon.ico')))
    

    Полный код index.js.

В результате выполненных действий файловая структура директории static должна иметь следующий вид:

static/
    images/
        favicon.ico
index.min.css
index.min.js

Изменения для серверного кода

server-changes

Директория server

  • Создайте поддиректории:

    • controllers — контроллеры;

    • helpers — хелперы;

    • middleware — модули промежуточного звена.

  • Создайте пустые JS-файлы для будущих модулей:

    • app.js — модуль монтирования промежуточных модулей (делает их доступными в приложении);

    • auth.js — модуль аутентификации на YouTube;

    • routes.js — модуль маршрутизации веб-запросов.

  • Добавьте следующий код в файл app.js.

  • Добавьте следующий код в файл routes.js.

  • Измените расширение файла config:

    config.js —> config.json

  • Отредактируйте файл config.json.

    Измените:

    module.exports = {
        staticFolder: 'static',
        defaultPort: 3000,
        cacheTTL: 30000,
        sessionSecret: 'REPLACE_ME_WITH_RANDOM_STRING'
    };
    

    На:

    {
      "staticFolder": "static",
      "defaultPort": 3000,
      "cacheTTL": 30000,
      "sessionSecret": "REPLACE_ME_WITH_RANDOM_STRING"
    }
    
  • Измените весь текущий контент файла index.js на следующий.

    Примечание. В index.js остается только функциональность, отвечающая за запуск приложения и прослушивание запросов на порте.

Директория controllers

  • Создайте пустой JS-файл:

    • index.js — контроллер обработки запросов и рендеринга HTML.

  • Добавьте следующий код в файл index.js.

Директория helpers

  • Создайте пустые JS-файлы:

    • index.js — входная точка для хелперов;

    • twitter.js — модуль-хелпер для работы с Twitter Search API;

    • youtube.js — модуль-хелпер для работы с YouTube Data API.

Директория middleware

  • Создайте пустой JS-файл:

    • auth.js — модуль проверки прохождения аутентификации на YouTube.

В результате выполненных действий файловая структура директории server должна иметь следующий вид:

server/
    controllers/
        index.js          # Контроллер обработки запросов и рендеринга HTML
    helpers/
        index.js          # Входная точка для модулей-хелперов (пустой)
        twitter.js        # Модуль-хелпер для работы с Twitter Search API (пустой)
        youtube.js        # Модуль-хелпер для работы с YouTube Data API (пустой)
    middleware/
        auth.js           # Модуль проверки прохождения аутентификации на YouTube (пустой)
    app.js                # Модуль монтирования промежуточных модулей
    auth.js               # Модуль аутентификации на YouTube (пустой)
    config.json           # Конфигурация приложения
    index.js              # Запуск приложения и прослушивание запросов на порте
    rebuild.js            # Модуль отслеживания изменений и перезапуска сервера
    render.js             # Рендеринг HTML
    routes.js             # Маршрутизатор

Получение OAuth-токенов

Сервисы Twitter и Google хранят различные данные пользователей — твиты, видео на Youtube, письма в Почте, фотографии и так далее. Чтобы обеспечить удобный доступ к этим данным из других приложений или сторонних сервисов, они используют открытый протокол авторизации OAuth 2.0.

Согласно протоколу, разработчик регистрирует приложение на OAuth-сервере и запрашивает доступ к определенным данным. Авторизованный пользователь разрешает или запрещает его.

Получение OAuth-токена для Twitter

Twitter предлагает приложениям возможность выдавать аутентифицированные запросы от имени самого приложения.

С чего начать?

Примечание. Postman необходим для получения OAuth-токена с помощью POST-запроса в обмен на код, полученный методом Base64.

Как закодировать строку?

Чтобы закодировать строку методом Base64:

  • Сформируйте строку вида: Consumer Key:Consumer Secret.

    Пример

    xvz1evFS4wEEPTGEFPHBog:L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg

    Примечание. Получить ключи Consumer Key и Consumer Secret можно, перейдя на вкладку Keys and Access Tokens вашего приложения.

  • Запустите терминал или Git Bash.

  • Выполните команду echo -n "xvz1evFS4wEEPTGEFPHBog:L8qq9PZyRg6ieKGEKhZolGC0vJWLw8iEJ88DRdyOg" | base64.

  • Скопируйте полученный код.

    Пример

    eHZ6MWV2RlM0d0VFUFRHRUZQSEdFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==

Примечание. Если возникли сложности, воспользуйтесь онлайн-ресурсом base64encode.org.

Как получить OAuth-токен в обмен на код?

Чтобы получить токен в обмен на код:

  • Запустите Postman.

    Примечание. По умолчанию открывается вкладка, в которой необходимо сформировать POST-запрос к OAuth-серверу Twitter.

  • Выберите тип запроса POST.

  • Введите адрес сервера https://api.twitter.com/oauth2/token.

  • Перейдите на вкладку Headers.

  • Введите в поле Key заголовок Authorization со значением (поле Value) Basic <закодированная строка Consumer Key:Consumer Secret>.

    Пример

    Authorization: Basic eHZ6MWV2RlM0d0VFUFRHRUZQSEdFS2hab2xHQzB2SldMdzhpRUo4OERSZHlPZw==

    Примечание. Basic указывает на базовый метод авторизации.

  • Введите второй заголовок Content-Type со значением application/x-www-form-urlencoded;charset=UTF-8.

    Пример

    Content-Type: application/x-www-form-urlencoded;charset=UTF-8

  • Перейдите на вкладку Body.

  • Выберите опцию x-www-form-urlencoded.

  • Введите в поле Key тело запроса grant_type со значением client_credentials.

  • Нажмите кнопку Send.

    OAuth-сервер вернет токен в JSON-формате:

    {
      "token_type": "bearer",
      "access_token": "AAAAAAAAAAAAAAAAAAAAAA%2FAAAAAAAAAA%3DAAAAAAAAAAAAAAAAAA"
    }
    

    Важно! Сохраните полученные токен и ключи (Consumer Key и Consumer Secret). Они необходимы для конфигурационного файла приложения.

Получение OAuth-токена для Google

Google предлагает приложениям возможность выдавать аутентифицированные запросы от имени самого приложения.

Примечание. За получение и обновление OAuth-токена с помощью POST-запроса в обмен на код авторизации отвечает модуль passport-youtube-v3.

С чего начать?

  • Изучите документацию.

  • Зарегистрируйте приложение и получите Client ID и Client Secret.

  • Укажите callback URL (в нашем случае это http://localhost:3000) в учетной записи вашего приложения.

  • Используйте полученные Client ID и Client Secret в запросах к YouTube Data API.

Важно! Сохраните полученные ключи (Client ID и Client Secret). Они необходимы для конфигурационного файла приложения.

Конфигурация приложения

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

  • Добавьте в файл server/config.json поле services.

    "services": {
      "twitter": {
        "consumer_key": "",
        "consumer_secret": "",
        "bearer_token": ""
      },
      "youtube": {
        "client_id": "",
        "client_secret": "",
        "redirect_url": "http://localhost:3000"
      }
    }
    

    Полный код config.json.

  • Заполните одноименные поля полученными данными.

  • Скройте файл server/config.json от системы контроля версий Git, чтобы случайно не добавить личные ключи в репозиторий файлов.

    # файл .gitignore
    server/config.json
    

    Полный код .gitignore.

Работа с Twitter Search API

Twitter Search API позволяет найти последние или популярные твиты, опубликованные на сайте Twitter.com за последние 7 дней.

Подробнее:

Доступ к API

Для успешного вызова API необходимы:

  • URL, составленный согласно требованиям к нужному запросу.

  • OAuth-токен, выданный вашему приложению для доступа к API.

  • Модуль twitter.

Вызов API

Изменения для работы с Twitter Search API:

twitter-changes

Директория controllers

  • Измените весь текущий контент файла index.js на следующий.

Директория helpers

  • Добавьте в файл index.js следующий контент:

    module.exports = {
        twitter: require('./twitter')
    };
    
  • Добавьте следующий код в файл twitter.js.

Работа с YouTube Data API

YouTube Data API позволяет найти видеоролики, опубликованные на сайте Youtube.com. По умолчанию в набор результата поиска включены следующие ресурсы: видео, каналы, списки воспроизведения.

Подробнее:

Доступ к API

Для успешного вызова API необходимы:

  • URL, составленный согласно требованиям к нужному запросу.

  • OAuth-токен, выданный вашему приложению для доступа к API.

  • Модуль googleapis.

Вызов API

Изменения для работы с YouTube Data API:

youtube-changes

Директория server

  • Добавьте следующий код в файл auth.js.

  • Отредактируйте файл routes.js.

    Измените:

    var router = require('express').Router(),
        controllers = require('./controllers');
    
    router
        .get('/ping/', function(req, res) {
            res.send('ok');
        })
        .get('/', controllers.getContent);
    
    module.exports = router;
    

    На:

    var router = require('express').Router(),
        controllers = require('./controllers'),
        passportYouTube = require('./auth'),
        middleware = require('./middleware/auth'),
        isAuthenticated = middleware.isAuthenticated;
    
    router
        .get('/auth/youtube', passportYouTube.authenticate('youtube'))
        .get('/auth/youtube/callback', passportYouTube.authenticate('youtube', { failureRedirect: '/error', failureFlash: true }), (req, res) => {
            res.redirect('/');
        })
        .get('/', isAuthenticated, controllers.getContent);
    
    module.exports = router;
    

Директория controllers

  • Измените весь текущий контент файла index.js на следующий.

Директория helpers

  • Добавьте в файл index.js следующий контент (см. комментарий):

    module.exports = {
        twitter: require('./twitter'),
        youtube: require('./youtube')        // Подключаем модуль `youtube.js`
    };
    
  • Добавьте следующий код в файл youtube.js.

Директория middleware

  • Добавьте в файл auth.js следующий контент:

    module.exports = {
        isAuthenticated: function(req, res, next) {
            if (req.isAuthenticated()) return next();
    
            return res.redirect('/auth/youtube');
        }
    };
    

Верстка

В данном документе первоочередное внимание уделено вопросу взаимодействия технологий БЭМ. Поэтому он не содержит описания верстки и клиентского JavaScript. Описание верстки привело бы к большему объему, а, значит, и к меньшей практической ценности этого документа.

Процесс верстки сведен к следующим шагам:

  • Удалите все блоки из директории common.blocks.

  • Склонируйте следующие блоки в директорию common.blocks.

  • Добавьте logo.svg в директорию static/images.

  • Перезапустите сервер: npm run dev.

Приложение Social Services Search Robot готово.

Не получилось?

Если при создании приложения возникли сложности, поищите решение на форуме. Если готового ответа не нашлось, задайте вопрос экспертам.

Если вы заметили ошибку или хотите чем-то дополнить статью, вы всегда можете или написать нам об этом на Гитхабе, или поправить статью с помощью prose.io.