> ## Documentation Index
> Fetch the complete documentation index at: https://www.ayrshare.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Огляд генерації JWT

> Створіть URL для прив'язки соціальних мереж для user profile.

export const PlansAvailable = ({plans = [], maxPackRequired}) => {
  let displayPlans = plans;
  if (plans && plans.length === 1) {
    const lowerCasePlan = plans[0].toLowerCase();
    if (lowerCasePlan === "business") {
      displayPlans = ["Launch", "Business", "Enterprise"];
    } else if (lowerCasePlan === "premium") {
      displayPlans = ["Premium", "Launch", "Business", "Enterprise"];
    }
  }
  return <Note>
Available on {displayPlans.length === 1 ? "the " : ""}
{displayPlans.join(", ").replace(/\b\w/g, l => l.toUpperCase())}{" "}
{displayPlans.length > 1 ? "plans" : "plan"}.

{maxPackRequired && <span onClick={() => window.open('https://www.ayrshare.com/docs/additional/maxpack', '_self')} className="flex items-center mt-2 cursor-pointer">
 <span className="px-1.5 py-0.5 rounded text-sm" style={{
    backgroundColor: '#C264B6',
    color: 'white',
    fontSize: '12px'
  }}>
   Max Pack required
 </span>
</span>}
</Note>;
};

<PlansAvailable plans={["business"]} maxPackRequired={false} />

[Ендпоінт generateJWT](/apis/profiles/generate-jwt) створює URL для прив'язки соціальних мереж для окремого User Profile.
Див. [Business Plan and Launch Plan API integration](/multiple-users/api-integration-business) для отримання додаткової інформації.

## Перемикання профілів

Щоб перемикатися між різними сесіями профілів (наприклад, під час тестування з кількома профілями), спочатку потрібно вийти з поточного профілю. Див. [Automatic Logout of a Profile Session](/multiple-users/api-integration-business#automatic-logout-of-a-profile-session) для інструкцій щодо правильного перемикання профілів.

## Private Key та Profile Key

### Де отримати Private Key

Файл Private Key (private.key) та зразковий JSON-файл Postman входять до вашого [Integration Package](/multiple-users/api-integration-business#integration-package), отриманого під час онбордингу.
Integration Package також можна завантажити на панелі розробника Ayrshare на сторінці API -> Integration Package.

### Використання Private Key

Ми рекомендуємо читати Private Key private.key з файлу та надсилати його як рядок у полі `privateKey`, що дозволяє зберегти всі символи, включно з переносами рядків.
Private Key має бути точним, тобто зі збереженням усіх символів, включно з переносами рядків.
Якщо ви вставляєте ключ у свій код, вам може знадобитися вручну замінити переноси рядків символом `\n` або URL-кодувати рядок.

Вставлення ключа безпосередньо в код часто спричиняє проблеми.

## Створення JSON Web Token

1-хвилинне відео, що пояснює, як згенерувати JSON Web Token (JWT):

<div class="video-container">
  <iframe width="380" height="200" src="https://www.youtube.com/embed/JI232HBWHWc" title="Generate a JSON Web Token" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" />
</div>

JWT URL дійсний протягом **5 хвилин**. Через 5 хвилин потрібно згенерувати новий JWT URL.
Див. [Max Pack `expiresIn`](/apis/profiles/generate-jwt-overview#jwt-expires-in) для додаткових опцій.

## Відкриття JWT URL

Відкривайте JWT URL у новій вкладці браузера, у новому вікні браузера або у View Controller на iOS.

Ви можете керувати [закриттям або перенаправленням](/multiple-users/api-integration-business#opening-and-closing-the-social-linking-url) нового вікна або вкладки.

<Note>
  Соціальні мережі не дозволяють відкривати URL у iFrame або приховувати схвалений партнерський
  origin domain profile.ayrshare.com.
</Note>

## Перевірка JWT URL

Ендпоінт `generateJWT` не перевіряє повернений JWT URL за замовчуванням.
Наприклад, якщо в `generateJWT` передано пошкоджений Private Key, URL все одно буде повернуто, а URL призведе до помилки 401.

Ви можете перевірити повернений JWT URL, додавши `verify: true` у параметри тіла `generateJWT`. Якщо JWT URL не вдасться перевірити, буде повернуто помилку. Наприклад, якщо з Private Key видалили символ, буде повернуто таке:

```json JWT Error theme={"system"}
{
  "action": "JWT",
  "status": "error",
  "code": 189,
  "message": "Error generating JWT. Check the sent parameters, such as the privateKey has no extra tabs, spaces, or newlines. Also the entire private.key file including -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY-----. Error: secretOrPrivateKey must be an asymmetric key when using RS256"
}
```

Ми рекомендуємо використовувати `verify: true` лише в непродакшн-середовищі, оскільки валідація потребує додаткового часу обробки.

## Тестування в Postman

**Рекомендується** спочатку протестувати створення JWT URL у [Postman](/testing/postman).
До Integration Package, який знаходиться на сторінці API Key Primary Profile у панелі керування, включено зразок конфігураційного JSON-файлу Postman, що містить усе необхідне для перевірки створення JWT URL.
Просто імпортуйте конфігураційний файл у Postman, заповніть свій Profile Key (знайдений у панелі розробника Ayrshare шляхом перемикання на профіль, який хочете протестувати) у полі *body* `profileKey` і натисніть синю кнопку *Send*.
Усі інші обов'язкові поля вже заповнені.

Ви також можете [згенерувати код із Postman](/testing/postman#auto-generate-api-code-with-postman) або прочитати файл ключа з каталогу чи бази даних.

## Instagram Link Method

Акаунти Instagram можна прив'язати [двома способами](/dashboard/connect-social-accounts/instagram): безпосередньо через **Instagram Login** або через **підключену Facebook Page**.
Який процес починається, коли користувач натискає кнопку Instagram на сторінці прив'язки соціальних мереж, зазвичай контролюється налаштуванням [Instagram Login](/multiple-users/manage-user-profiles#instagram-login) на рівні акаунту в панелі керування.

Параметр тіла `instagramLinkMethod` [ендпоінту generateJWT](/apis/profiles/generate-jwt) дозволяє перевизначити це налаштування для окремого URL прив'язки:

| Значення    | Процес прив'язки Instagram                              |
| ----------- | ------------------------------------------------------- |
| `instagram` | Пряме входження в Instagram. Facebook Page не потрібна. |
| `facebook`  | Прив'язка через підключену Facebook Page.               |

Наприклад, якщо ваш стандарт акаунту — прив'язка через Facebook Page, наступне примусово встановить пряме входження в Instagram лише для цієї сесії прив'язки:

```json Instagram Link Method theme={"system"}
{
  "instagramLinkMethod": "instagram"
}
```

Згенерований JWT URL включатиме перевизначення, і натискання кнопки Instagram на сторінці прив'язки запустить запитаний процес на час цієї сесії — включно через перенаправлення авторизації Instagram/Facebook.

Кілька моментів, які варто знати:

* Перевизначення застосовується лише до сторінки прив'язки, відкритої з поверненого URL. Воно не змінює налаштування Instagram Login на рівні акаунту та не впливає на інші сесії прив'язки.
* Якщо `instagramLinkMethod` пропущено, сторінка прив'язки використовує налаштування вашого акаунту, як і раніше.
* Якщо надіслано недійсне значення, повертається помилка `400` зі списком допустимих значень (`instagram`, `facebook`).
* Перегляньте [відмінності функцій](/multiple-users/manage-user-profiles#direct-instagram-login-vs-facebook-page-authentication) між двома процесами перед вибором перевизначення — деякі функції Instagram, такі як пошук хештегів і колаборації, доступні лише за автентифікації через Facebook Page.

## JWT Expires In

<PlansAvailable plans={["business"]} maxPackRequired />

Якщо ви хочете, щоб JWT був дійсним довше стандартних 5 хвилин, додайте поле `expiresIn`.

Наприклад, надішліть наступний JSON, щоб установити JWT URL дійсним протягом 30 хвилин:

```json JWT Expires In theme={"system"}
{
  "expiresIn": 30
}
```

Це дозволяє [надіслати посилання електронною поштою](/apis/profiles/generate-jwt-overview#connect-accounts-email) своїм користувачам, замість того щоб вони переходили до вашого застосунку або платформи.
Поширений випадок використання — коли вашому користувачу потрібно повторно підключити соціальний акаунт, ви можете надіслати йому JWT-посилання електронною поштою, щоб він міг напряму повторно прив'язати соціальний акаунт, не переходячи до вашої платформи.

<Warning>
  Обов'язково обговоріть зі своєю командою безпеки, як довго ваш бізнес хоче тримати JWT активним.
  Довші терміни закінчення дії створюють додатковий ризик доступу до посилання неавторизованою стороною.
</Warning>

## Інтеграції

### Bubble.io JWT

Якщо ви користувач Bubble, будь ласка, див. *Generate JWT Token* у розділі Bubble.io для отримання інструкцій:

<Card title="Bubble Generate JWT" icon="link" href="/packages-guides/bubble#generate-jwt-token-in-bubble" horizontal />

### Мобільний JWT

Наведені нижче приклади [мобільного коду](/apis/profiles/generate-jwt-overview#mobile-code-examples) на Swift, Flutter та React Native показують, як запустити сторінку прив'язки соціальних мереж на пристрої iOS.
Замініть строкову змінну `jwtURL` на значення, повернуте з [ендпоінту /generateJWT](/apis/profiles/generate-jwt).

#### Swift (iOS)

У Swift використовуйте `UIViewController` та `SFSafariViewControllerDelegate`.
Ми не рекомендуємо використовувати `WebView`, оскільки деякі соціальні мережі, такі як Facebook і Google, блокують автентифікацію.

#### Flutter (Dart)

У Flutter (Dart) немає прямого еквівалента `UIViewController` або `SFSafariViewController`.
Однак ви можете досягти подібної функціональності, використовуючи пакет `url_launcher` для відкриття веб-URL.

#### React Native

React Native також не має прямого еквівалента `SFSafariViewController`, але ви можете досягти подібного результату за допомогою API `WebBrowser`, наданого `expo-web-browser`, який відкриває URL у модальному вікні браузера, що ділиться cookies із системним браузером. Крім того, ви можете використовувати вбудовану функцію React Native `Linking`, щоб відкрити Safari: `await Linking.canOpenURL(jwtURL);`

#### Приклади мобільного коду

<CodeGroup>
  ```swift Swift theme={"system"}
  import UIKit
  import SafariServices

  class ViewController: UIViewController, SFSafariViewControllerDelegate {
      
      var jwtURL = "https://profile.ayrshare.com?domain=acme&jwt=eyJhbGciOiJ"

      override func viewDidLoad() {
          super.viewDidLoad()
          setupButton()
      }
      
      func setupButton() {
          let button = UIButton(type: .system)
          button.frame = CGRect(x: (view.bounds.width - 200) / 2, y: (view.bounds.height - 50) / 2, width: 200, height: 50)
          button.setTitle("Open URL", for: .normal)
          button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
          view.addSubview(button)
      }

      @objc func buttonTapped() {
          openURLInInAppBrowser()
      }

      func openURLInInAppBrowser() {
          if let url = URL(string: jwtURL) {
              let safariVC = SFSafariViewController(url: url)
              safariVC.delegate = self
              present(safariVC, animated: true, completion: nil)
          }
      }

      // Optional: If you want to handle when the in-app browser is closed
      func safariViewControllerDidFinish(_ controller: SFSafariViewController) {
          controller.dismiss(animated: true, completion: nil)
      }
  }
  ```

  ```dart Flutter theme={"system"}
  /** yaml dependencies
    dependencies:
      flutter:
        sdk: flutter
      url_launcher: ^6.2.1
  */

  import 'package:flutter/material.dart';
  import 'package:url_launcher/url_launcher.dart';

  void main() {
    runApp(MyApp());
  }

  class MyApp extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
      return MaterialApp(
        title: 'URL Launcher Example',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      );
    }
  }

  class MyHomePage extends StatelessWidget {
    final String jwtURL = "https://profile.ayrshare.com?domain=acme&jwt=eyJhbGciOiJ";

    @override
    Widget build(BuildContext context) {
      return Scaffold(
        appBar: AppBar(
          title: Text('URL Launcher Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
              openURLInBrowser(context);
            },
            child: Text('Open URL'),
          ),
        ),
      );
    }

    void openURLInBrowser(BuildContext context) async {
      if (await canLaunch(jwtURL)) {
        await launch(jwtURL);
      } else {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Could not launch $jwtURL'),
          ),
        );
      }
    }
  }
  ```

  ```jsx React Native theme={"system"}
  /**
  • Using the API provided by expo-web-browser,
  • which opens a URL in a modal browser window that shares cookies
  • with the system browser.

  • Learn more about expo: https://reactnative.dev/docs/environment-setup?guide=quickstart
  • and running the following command:
  • expo install expo-web-browser
  */

  import React from 'react';
  import { StyleSheet, Button, View } from 'react-native';
  import * as WebBrowser from 'expo-web-browser';

  export default function App() {
    const jwtURL = 'https://profile.ayrshare.com?domain=acme&jwt=eyJhbGciOiJ';

    const openURLInBrowser = async () => {
      try {
        await WebBrowser.openBrowserAsync(jwtURL);
        // Optional: WebBrowser.openBrowserAsync returns a promise that resolves with an object containing
        // 'type' that can be 'cancelled' or 'dismissed'. You can use this to handle when the browser is closed.
      } catch (error) {
        console.error(error);
      }
    };

    return (
      <View style={styles.container}>
        <Button title="Open URL" onPress={openURLInBrowser} />
      </View>
    );
  }

  const styles = StyleSheet.create({
    container: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
    },
  });
  ```
</CodeGroup>

## Connect Accounts Email

<max_pack />

Разом з опцією довшого часу закінчення дії ви можете автоматично налаштувати Ayrshare, щоб вашим користувачам надсилалося посилання на сторінку прив'язки соціальних мереж електронною поштою.

### Connect Accounts JSON

Наприклад, наступний JSON надішле електронний лист на `john@user.com` із назвою компанії ACME, контактною електронною адресою `support@mycompany.com` та посиланнями на умови використання та політику конфіденційності:

```json Example Contact Email Request theme={"system"}
/**
  All fields are in the email object required.
  Missing fields will cause the email to fail.
*/
{
  "email": {
    "to": "john@user.com",
    "contactEmail": "support@mycompany.com",
    "company": "ACME",
    "termsUrl": "https://www.ayrshare.com/terms",
    "privacyUrl": "https://www.ayrshare.com/privacy",
    "expiresIn": 60
  }
}
```

Відповідь включатиме наступне, якщо було встановлено email та час закінчення дії:

```json Example Contact Email Response theme={"system"}
{
  "emailSent": true,
  "expiresIn": "30m"
}
```

### Приклад JWT Connect Accounts Email

Ось приклад електронного листа з посиланням Connect Account, що відкриває сторінку прив'язки соціальних мереж:

<img src="https://mintcdn.com/ayrshare-docs/Nmrhj2Gh7WSf62Bh/images/apis/profiles/jwt-email.webp?fit=max&auto=format&n=Nmrhj2Gh7WSf62Bh&q=85&s=fbe4ee86ca59c26a5bd5b289fda96b8b" alt="JWT Email" width="563" class="center" data-path="images/apis/profiles/jwt-email.webp" />

Лист надійде з адреси:

`Social Connect Hub <connect@socialconnecthub.com>`
