[Документация Yandex Cloud](../../index.md) > [Yandex DataLens](../index.md) > Публикация и встраивание > Встраивание через JWT

# Встраивание через JWT

Вы можете безопасно встроить непубличные [чарты](../concepts/chart/index.md) и [дашборды](../concepts/dashboard.md) на сайт или в приложение с помощью специальных ссылок с [JWT-токеном](https://ru.wikipedia.org/wiki/JSON_Web_Token).

Встраивание непубличных объектов работает только в новой объектной модели DataLens на уровне [воркбуков](../workbooks-collections/index.md) и доступно только [администратору](roles.md#datalens-workbooks-admin) воркбука.

Встраивание не поддерживается для непубличных объектов, которые построены на основе следующих подключений: {#unsupported-connections}


* [Snowflake](../operations/connection/create-snowflake.md)
* [Metrica](../operations/connection/create-metrica-api.md)
* [AppMetrica](../operations/connection/create-appmetrica.md)
* [Yandex Cloud Billing](../operations/connection/create-cloud-billing.md)
* [DataLens Usage Analytics](../operations/connection/create-usage-tracking.md)
* [SpeechSense](../operations/connection/create-speechsense.md) (чтобы встраивать объекты, создайте подключение от имени сервисного аккаунта)

{% note info %}

Дашбордом или чартом на основе данных Метрики или AppMetrica можно [поделиться](../concepts/datalens-public.md#metrica-share).

{% endnote %}

## Параметры отображения {#view-parameters}

Функциональность и внешний вид встраиваемых объектов можно определить с помощью специальных параметров, передаваемых в ссылке:

* `_autoupdate` — задает время [автообновления](../dashboard/settings.md#auto-update) для дашбордов и чартов в секундах. По умолчанию они не обновляются автоматически. Работает только на активной вкладке браузера. Если для неактивной вкладки время автообновления уже наступило, оно выполнится, когда вкладка снова станет активной. Минимальная величина:

  * для дашбордов — 30 секунд;
  * для чартов — 15 секунд.

* `_reload_on_session_expire` — задает автоматическую перезагрузку страницы по истечении времени жизни сессии. Значение для включения параметра — `1`.
* `_theme` — задает оформление объекта. Возможные значения:

  * `light` — для отображения в светлой теме;
  * `dark` — для отображения в темной теме.

* `_lang` — у чартов определяет значение языка для меню, которое открывается при нажатии на значок ![image](../../_assets/console-icons/ellipsis.svg). Возможные значения: `ru` или `en`.
* `_no_tabs ` — скрывает вкладки у дашборда. Значение для включения параметра — `1`.
* `_no_table_of_content` — скрывает содержание у дашборда. Значение для включения параметра — `1`.
* `_no_title` — скрывает заголовок у дашборда. Значение для включения параметра — `1`.

Параметры передаются в формате `<имя_параметра>=<значение>`. Например, чтобы задать время автообновления 50 секунд, укажите: `_autoupdate=50`.

Параметр добавляется к адресу объекта после знака вопроса `?` перед хешем с токеном. Их можно передавать вместе с [неподписанными параметрами](#unsigned-parameters). Для передачи нескольких параметров перечислите их через знак амперсанда `&`.

## Как встроить непубличный объект {#how-to-private-embed}

1. Создайте ключ для встраивания:

   {% note info %}

   Один ключ можно использовать для встраивания нескольких объектов.

   {% endnote %}

   1. Перейдите на [главную страницу](https://datalens.ru/?skipPromo=true) DataLens.
   1. На панели слева выберите ![collections](../../_assets/console-icons/rectangles-4.svg) **Коллекции и воркбуки**.
   1. Откройте воркбук, в котором расположен объект для встраивания.
   1. В верхней части интерфейса нажмите значок ![ellipsis](../../_assets/console-icons/ellipsis.svg) и выберите ![key](../../_assets/console-icons/key.svg) **Ключи для встраивания**.

      ![image](../../_assets/datalens/security/embedding-keys.png)

   1. В открывшемся окне:

      1. Нажмите кнопку ![plus](../../_assets/console-icons/plus.svg) **Создать ключ**.
      1. Введите название ключа и нажмите кнопку **Создать**.
      1. Внизу нажмите кнопку **Скачать файл с ключом** или скопируйте значение ключа.

         {% note warning %}

         После закрытия окна все данные из него будут потеряны.

         {% endnote %}

         Новый ключ для встраивания появится в списке.

1. Настройте встраивание для непубличного объекта:

   {% note info %}

   Для каждого объекта можно настроить несколько встраиваний.

   {% endnote %}

   1. В строке с нужным объектом нажмите значок ![ellipsis](../../_assets/console-icons/ellipsis.svg) и выберите **Настройки встраивания**.

      ![image](../../_assets/datalens/security/embedding-settings.png)

   1. В открывшемся окне нажмите кнопку ![plus](../../_assets/console-icons/plus.svg) **Новое встраивание**.
   1. В окне настроек укажите:

      {% list tabs group=datalens_public %}

      - Для чарта {#chart}

        * **Название** — введите название встраивания.
        * **Ключ** — выберите созданный ранее ключ для встраивания.
        * Выберите **Режим работы параметров по умолчанию**:

          * **Всё разрешено** (по умолчанию) — все [неподписанные параметры](#unsigned-parameters) разрешены, кроме запрещенных;
          * **Всё запрещено** — все неподписанные параметры запрещены, кроме разрешенных.

          На [подписанные параметры](#signed-parameters) из токена эти ограничения не действуют.

        * (опционально) **Запрещённые параметры** — укажите названия неподписанных параметров, которые не будут работать при встраивании чарта. Доступно для режима **Всё разрешено**.
        * (опционально) **Разрешённые параметры** — укажите названия неподписанных параметров, которые можно передавать в ссылке для встраивания. Параметры, которые не указаны в этом списке, будут проигнорированы при попытке передать их в ссылке для встраивания. Доступно для режима **Всё запрещено**.
        * (опционально) **Разрешить экспорт данных** — включите отображение меню, которое позволяет экспортировать данные, представленные на чарте. Для экспорта данных наведите курсор на чарт и в правом верхнем углу нажмите ![image](../../_assets/console-icons/ellipsis.svg) → ![image](../../_assets/console-icons/arrow-down-to-line.svg) **Сохранить как** и выберите формат: `XLSX`, `CSV` или `Markdown`.

      - Для дашборда {#dashboard}

        * **Название** — введите название встраивания.
        * **Ключ** — выберите созданный ранее ключ для встраивания.
        * (опционально) **Запрещённые параметры** — укажите названия [неподписанных параметров](#unsigned-parameters), которые не будут работать при встраивании дашборда. На [подписанные параметры](#signed-parameters) из токена эти ограничения не действуют. По умолчанию в ссылке для встраивания можно передавать любые параметры. Если они [указаны](../operations/dashboard/add-parameters.md) в настройках дашборда, то могут повлиять на чарты и селекторы.

          {% note info %}

          Если на дашборде есть селекторы с запрещенными параметрами, при встраивании такие селекторы будут недоступны для использования.

          {% endnote %}

        * (опционально) **Разрешить экспорт данных** — включите отображение меню, которое позволяет экспортировать данные, представленные на чарте. Для экспорта данных наведите курсор на чарт и в правом верхнем углу нажмите ![image](../../_assets/console-icons/ellipsis.svg) → ![image](../../_assets/console-icons/arrow-down-to-line.svg) **Сохранить как** и выберите формат: `XLSX`, `CSV` или `Markdown`.

      {% endlist %}

   1. Нажмите кнопку **Создать**. В колонке **ID** скопируйте идентификатор объекта встраивания, а затем нажмите **Закрыть**.

1. Создайте токен:

   1. Подготовьте payload для токена — полезную нагрузку, которая содержит информацию об объекте встраивания. Полезная нагрузка содержит следующие поля:

      * `embedId` — идентификатор объекта встраивания.
      * `iat` — время выписки токена JWT в формате [Unix Timestamp](https://ru.wikipedia.org/wiki/Unix_time).
      * `exp` — время окончания действия токена в формате Unix Timestamp.

        {% note warning %}

        Токены, в которых разница между `exp` и `iat` превышает 10 часов, считаются невалидными.

        {% endnote %}

      * `dlEmbedService` — строковая константа идентификатора сервиса: `YC_DATALENS_EMBEDDING_SERVICE_MARK`.
      * (опционально) `params` — подписанные параметры чарта, которые передаются в составе токена. Их нельзя изменить без повторной генерации токена.

        {% note warning %}

        * Генерируемый токен передается в составе заголовка сетевого запроса, поэтому его максимальный размер ограничен — 30 КБ. Учитывайте это при использовании подписанных параметров.
        * Для корректной работы в качестве значений параметров используйте только строку или массив строк.

        {% endnote %}

        Пример:

        ```json
        {
          "embedId": "ieez7********",
          "iat": 1516239022,
          "exp": 1516240822,
          "dlEmbedService": "YC_DATALENS_EMBEDDING_SERVICE_MARK",
          "params": {
            "param1": "value1",
            "param2": "value2"
          }
        }
        ```

   1. Чтобы создать JWT-токен, подпишите подготовленный payload закрытым ключом, который был получен ранее при создании ключа для встраивания.

      {% note info %}

      Используйте при создании JWT алгоритм `PS256`.

      {% endnote %}

      Для создания JWT-токена используйте примеры кода:

      {% list tabs group=programming_language %}

      - Python {#python}

        Установите модуль `cryptography` для работы с алгоритмом `PS256`:

        ```bash
        pip3 install cryptography
        pip3 install PyJWT
        ```

        {% note info %}

        Для корректной работы используйте PyJWT версии не ниже 2.0.0.
        
        {% endnote %}

        Выполните код:

        ```python
        import time
        import jwt
        import json
        ​
        private_key = b"""<закрытый_ключ>"""
        ​
        now = int(time.time())
        payload = {
           'embedId': "<идентификатор_объекта_встраивания>",
           'dlEmbedService': "YC_DATALENS_EMBEDDING_SERVICE_MARK",
           'iat': now,
           'exp': now + 360,
           "params": {  }}
           ​
        # JWT generation.
        encoded_token = jwt.encode(
           payload,
           private_key,
           algorithm='PS256',
           )

        print(encoded_token)
        ```

      - Node.js {#node}

        Установите пакет [jsonwebtoken](https://github.com/auth0/node-jsonwebtoken) с помощью [npm](https://www.npmjs.com/):

        ```bash
        npm install jsonwebtoken
        ```

        Выполните код:

        ```js
        const privateKey = `<закрытый_ключ>`;

        const now = Math.floor(Date.now() / 1000);
        const payload = {
        embedId: '<идентификатор_объекта_встраивания>',
        dlEmbedService: 'YC_DATALENS_EMBEDDING_SERVICE_MARK',
        iat: now,
        exp: now + 360,
        params: {},
        };

        const jwt = require('jsonwebtoken');

        const encodedToken = jwt.sign(payload, privateKey, {
        algorithm: 'PS256',
        });

        console.log(encodedToken);
        ```

      - Go {#go}

        Установите пакет [jwt-go](https://github.com/golang-jwt/jwt):

        ```bash
        go install github.com/golang-jwt/jwt/v5@latest
        ```

        Выполните код:

        ```golang
        
        package main

        import (
          "fmt"
          "time"

          "github.com/golang-jwt/jwt/v5"
        )

        func main() {
          privateKey, err := jwt.ParseRSAPrivateKeyFromPEM([]byte(`<закрытый_ключ>`))

          now := time.Now().Unix()
          payload := jwt.MapClaims{
              "embedId":        "<идентификатор_объекта_встраивания>",
              "dlEmbedService": "YC_DATALENS_EMBEDDING_SERVICE_MARK",
              "iat":            now,
              "exp":            now + 360,
              "params":         map[string]interface{}{},
          }

          token := jwt.NewWithClaims(jwt.SigningMethodPS256, payload)
          signedToken, err := token.SignedString(privateKey)
          if err != nil {
              fmt.Println("Error generating token:", err)
              return
          }

          fmt.Println(signedToken)
        }
        ```

      {% endlist %}

   1. Сформируйте ссылку для встраивания:

      {% list tabs group=datalens_public %}

      - Для чарта {#chart}

                
        ```bash
        https://datalens.ru/embeds/chart#dl_embed_token=<токен>
        ```


        Где:

        * `<токен>` — JWT-токен.

      - Для дашборда {#dashboard}

                
        ```bash
        https://datalens.ru/embeds/dash#dl_embed_token=<токен>
        ```


        Где:

        * `<токен>` — JWT-токен.

      {% endlist %}

1. Добавьте ссылку для встраивания на свой сайт или в приложение. Например:

      {% list tabs group=datalens_public %}

      - Для чарта {#chart}

                
        ```html
        <iframe src="https://datalens.ru/embeds/chart#dl_embed_token=<токен>" width="600" height="400" frameborder="0"></iframe>
        ```


        Где:
        
        * `src` — URL встраивания.
        * `<токен>` — JWT-токен.
        * `width` — ширина чарта.
        * `height` — высота чарта.
        * `frameborder` — наличие рамки для чарта.

      - Для дашборда {#dashboard}

                
        ```html
        <iframe src="https://datalens.ru/embeds/dash#dl_embed_token=<токен>" width="600" height="400" frameborder="0"></iframe>
        ```


        Где:

        * `src` — URL встраивания.
        * `<токен>` — JWT-токен.
        * `width` — ширина дашборда.
        * `height` — высота дашборда.
        * `frameborder` — наличие рамки для дашборда.

      {% endlist %}

      {% note info %}

      Если на сайте и в приложении, куда будет встроен чарт или дашборд, реализована политика доступа по белым спискам, добавьте домен `https://datalens.ru` в список разрешенных.

      {% endnote %}

## Обновление токена без потери состояния фильтров {#token-update}

При замене JWT-токена в ссылке для встраивания фильтры на встроенном дашборде сбрасываются к значениям по умолчанию.

Чтобы обновить ссылку для встраивания без потери состояния фильтров, используйте метод [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).

Для обновления в ссылке JWT-токена отправьте в `iframe` с помощью метода `postMessage` объект вида:

```js
{
    type: 'SECURE_EMBEDDING_TOKEN_UPDATE',
    token: <обновленный_токен>
}
```

Где `<обновленный_токен>` — обновленный JWT-токен.

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

Пример:


```js
const iframe = document.getElementById('ID_IFRAME');

iframe.contentWindow.postMessage({
    type: 'SECURE_EMBEDDING_TOKEN_UPDATE',
    token: 'NEW_TOKEN'
}, 'https://datalens.ru/');
```


Учитывайте время окончания действия токена при его обновлении.

## Неподписанные параметры {#unsigned-parameters}

По умолчанию в ссылке для встраивания объекта можно передавать любые параметры, кроме явно запрещенных. Они указываются в URL перед хешем с токеном. Это позволяет изменять некоторые параметры виджета или дашборда на стороне клиента без повторного создания токена.

Например, если в чарте или дашборде используются параметры `from` и `to` для фильтрации по времени, можно передавать эти параметры в ссылке для встраивания перед хешем с токеном:

{% list tabs group=datalens_public %}

- Для чарта {#chart}

    
  ```html
  <iframe src="https://datalens.ru/embeds/chart?from=2022-01-01&to=2023-02-05#dl_embed_token=<токен>" width="600" height="400" frameborder="0"></iframe>
  ```


  Где:

  * `src` — URL встраивания.
  * `<токен>` — JWT-токен.
  * `from=2022-01-01&to=2023-02-05` — неподписанные параметры.

- Для дашборда {#dashboard}

    
  ```html
  <iframe src="https://datalens.ru/embeds/dash?from=2022-01-01&to=2023-02-05#dl_embed_token=<токен>" width="600" height="400" frameborder="0"></iframe>
  ```


  Где:

  * `src` — URL встраивания.
  * `<токен>` — JWT-токен.
  * `from=2022-01-01&to=2023-02-05` — неподписанные параметры.

{% endlist %}

Неподписанные параметры будут проигнорированы в ссылке для встраивания, если:

{% list tabs group=datalens_public %}

- Для чарта {#chart}

  * название параметра есть в списке запрещенных в режиме **Всё разрешено**;
  * название параметра нет в списке разрешенных в режиме **Всё запрещено**.

- Для дашборда {#dashboard}

  Названия параметра есть в списке запрещенных.

{% endlist %}

## Подписанные параметры {#signed-parameters}

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

Настройки встраивания для разрешенных и запрещенных параметров не действуют на подписанные параметры. Они будут переданы в чарты и селекторы в любом случае.

Подписанные параметры можно динамически обновить с помощью [обновления токена без потери состояния фильтров](#token-update).

Особенности работы с параметрами:

* Значения подписанных параметров приоритетны. Если в виджет прокидываются одновременно подписанный параметр и внешний параметр с тем же именем, применяется подписанный.
* Селекторы по подписанным параметрам не влияют на чарты дашборда.

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

## Рекомендации {#recommendations}

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

* Значения по умолчанию передавайте через параметры в ссылке.
* Учитывайте, что приоритет значения параметра в ссылке выше, чем значение подписанного параметра с таким же названием.
* Чтобы запретить изменение значения параметра, добавьте [подписанный параметр](#signed-parameters) в токен.

## Особенности встраивания дашбордов {#dash-embed-specialties}

При встраивании дашбордов учитывайте следующие особенности:

* Встроенные дашборды открываются только в режиме просмотра. У них скрыта панель навигации и по умолчанию скрыто меню ![image](../../_assets/console-icons/ellipsis.svg) у чартов. Включите опцию **Разрешить экспорт данных** в настройках встраивания, чтобы у чартов отображалось меню ![image](../../_assets/console-icons/ellipsis.svg), которое позволяет экспортировать данные, представленные на чарте.
* При открытии встроенного дашборда действуют его [настройки](../dashboard/settings.md).
* Для корректной работы неподписанных параметров [укажите их](../operations/dashboard/add-parameters.md) в настройках дашборда.
* Неподписанные параметры работают так же, как обычные [параметры в ссылке дашборда](../dashboard/dashboard_parameters.md#params-in-url).
* Нельзя передать состояние отфильтрованных чартов в параметре `state`.
* В ссылке для встраивания нельзя указать заголовок дашборда.
* В ссылке для встраивания в параметре `tab` можно указать, на какой вкладке открывать дашборд.