> ## 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.

# Tổng quan Generate JWT

> Tạo URL liên kết mạng xã hội cho một 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} />

[Endpoint generateJWT](/apis/profiles/generate-jwt) tạo một URL liên kết mạng xã hội cho một User Profile duy nhất.
Xem [tích hợp API Business Plan và Launch Plan](/multiple-users/api-integration-business) để biết thêm chi tiết.

## Chuyển đổi Profile

Để chuyển đổi giữa các phiên profile khác nhau (ví dụ khi thử nghiệm với nhiều profile), bạn cần đăng xuất profile hiện tại trước. Xem [Tự động đăng xuất phiên Profile](/multiple-users/api-integration-business#automatic-logout-of-a-profile-session) để biết hướng dẫn về cách xử lý chuyển đổi profile đúng cách.

## Private Key và Profile Key

### Nơi lấy Private Key

Tệp Private Key (private.key) và một tệp Postman JSON mẫu được bao gồm trong [Integration Package](/multiple-users/api-integration-business#integration-package) mà bạn nhận được trong quá trình onboarding.
Integration Package cũng có thể được truy xuất trong bảng điều khiển nhà phát triển Ayrshare tại trang API -> Integration Package.

### Sử dụng Private Key

Chúng tôi khuyến nghị đọc Private Key private.key từ tệp và gửi dưới dạng chuỗi trong trường `privateKey`, cho phép bạn bảo toàn tất cả các ký tự bao gồm ký tự xuống dòng.
Private Key phải chính xác, tức là bảo toàn tất cả các ký tự bao gồm ký tự xuống dòng.
Nếu bạn dán key vào code, bạn có thể cần thay thế thủ công ký tự xuống dòng bằng ký tự `\n` hoặc URL encode chuỗi đó.

Dán key trực tiếp vào code thường gây ra sự cố.

## Tạo một JSON Web Token

Video 1 phút giải thích cách tạo 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>

URL JWT có hiệu lực trong **5 phút**. Sau 5 phút bạn phải tạo URL JWT mới.
Xem [Max Pack `expiresIn`](/apis/profiles/generate-jwt-overview#jwt-expires-in) để biết các tùy chọn bổ sung.

## Mở URL JWT

Mở URL JWT trong một tab trình duyệt mới, cửa sổ trình duyệt mới, hoặc View Controller trên iOS.

Bạn có thể kiểm soát việc [đóng hoặc chuyển hướng](/multiple-users/api-integration-business#opening-and-closing-the-social-linking-url) của cửa sổ hoặc tab mới.

<Note>
  Các mạng xã hội không cho phép mở URL trong iFrame hoặc che giấu tên miền đối tác đã được phê duyệt
  profile.ayrshare.com.
</Note>

## Xác minh URL JWT

Endpoint `generateJWT` mặc định không xác thực URL JWT được trả về.
Ví dụ, nếu một Private Key bị hỏng được truyền vào `generateJWT`, một URL vẫn sẽ được trả về nhưng URL sẽ dẫn đến lỗi 401.

Bạn có thể xác minh URL JWT được trả về bằng cách bao gồm `verify: true` trong các tham số body của `generateJWT`. Nếu URL JWT không thể được xác thực, một lỗi sẽ được trả về. Ví dụ, nếu Private Key bị loại bỏ một ký tự, kết quả sau sẽ được trả về:

```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"
}
```

Chúng tôi khuyến nghị chỉ sử dụng `verify: true` trong môi trường không phải production vì việc xác thực mất thêm thời gian xử lý.

## Thử nghiệm trong Postman

**Khuyến nghị** thử nghiệm việc tạo URL JWT trong [Postman](/testing/postman) trước.
Được bao gồm trong Integration Package, tìm thấy trong trang API Key của Primary Profile trên bảng điều khiển, là một tệp JSON cấu hình Postman mẫu bao gồm mọi thứ bạn cần để xác minh việc tạo URL JWT.
Chỉ cần import tệp cấu hình vào Postman, điền Profile Key của bạn (tìm thấy trong bảng điều khiển nhà phát triển Ayrshare bằng cách chuyển sang profile bạn muốn thử nghiệm) vào trường *body* `profileKey`, và nhấn nút *Send* màu xanh.
Tất cả các trường bắt buộc khác đã được điền sẵn.

Bạn cũng có thể [tạo code từ Postman](/testing/postman#auto-generate-api-code-with-postman), hoặc đọc tệp key từ một thư mục hoặc cơ sở dữ liệu.

## Phương thức liên kết Instagram

Tài khoản Instagram có thể được liên kết theo [hai cách](/dashboard/connect-social-accounts/instagram): trực tiếp với **Instagram Login**, hoặc thông qua **Facebook Page đã kết nối**.
Luồng nào bắt đầu khi người dùng nhấp vào nút Instagram trên trang liên kết mạng xã hội thường được kiểm soát bởi cài đặt [Instagram Login](/multiple-users/manage-user-profiles#instagram-login) toàn tài khoản trong bảng điều khiển.

Tham số body `instagramLinkMethod` của [endpoint generateJWT](/apis/profiles/generate-jwt) cho phép bạn ghi đè cài đặt đó cho một URL liên kết duy nhất:

| Giá trị     | Luồng liên kết Instagram                                |
| ----------- | ------------------------------------------------------- |
| `instagram` | Instagram Login trực tiếp. Không yêu cầu Facebook Page. |
| `facebook`  | Liên kết thông qua Facebook Page đã kết nối.            |

Ví dụ, nếu mặc định của tài khoản là liên kết Facebook Page, JSON sau đây sẽ buộc Instagram Login trực tiếp chỉ cho phiên liên kết này:

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

URL JWT được tạo sẽ bao gồm ghi đè này, và việc nhấp vào nút Instagram trên trang liên kết sẽ khởi động luồng được yêu cầu trong suốt phiên đó — bao gồm cả trong quá trình chuyển hướng ủy quyền Instagram/Facebook.

Một vài điều cần biết:

* Ghi đè chỉ áp dụng cho trang liên kết được mở từ URL được trả về. Nó không thay đổi cài đặt Instagram Login toàn tài khoản của bạn hoặc ảnh hưởng đến các phiên liên kết khác.
* Nếu `instagramLinkMethod` bị bỏ qua, trang liên kết sử dụng cài đặt toàn tài khoản của bạn, giống như trước đây.
* Nếu một giá trị không hợp lệ được gửi, lỗi `400` sẽ được trả về liệt kê các giá trị hợp lệ (`instagram`, `facebook`).
* Xem lại [sự khác biệt về tính năng](/multiple-users/manage-user-profiles#direct-instagram-login-vs-facebook-page-authentication) giữa hai luồng trước khi chọn ghi đè — một số tính năng Instagram, như tìm kiếm hashtag và cộng tác, chỉ khả dụng với xác thực Facebook Page.

## JWT Expires In

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

Nếu bạn muốn thời gian hết hạn JWT lâu hơn 5 phút mặc định, hãy bao gồm trường `expiresIn`.

Ví dụ, gửi JSON sau để đặt URL JWT có hiệu lực trong 30 phút:

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

Điều này cho phép bạn [gửi liên kết qua email](/apis/profiles/generate-jwt-overview#connect-accounts-email) đến người dùng của bạn thay vì họ phải vào ứng dụng hoặc nền tảng của bạn.
Một trường hợp sử dụng phổ biến là khi người dùng của bạn cần kết nối lại một social account, bạn có thể gửi email cho họ liên kết JWT để liên kết lại social account trực tiếp thay vì phải điều hướng đến nền tảng của bạn.

<Warning>
  Hãy xem xét với đội bảo mật của bạn thời gian doanh nghiệp của bạn muốn giữ JWT sống bao lâu.
  Thời gian hết hạn dài hơn tạo thêm rủi ro về việc bên trái phép truy cập liên kết.
</Warning>

## Tích hợp

### Bubble.io JWT

Nếu bạn là người dùng Bubble, vui lòng xem *Generate JWT Token* trong phần Bubble.io để có hướng dẫn:

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

### Mobile JWT

Các [ví dụ mã mobile](/apis/profiles/generate-jwt-overview#mobile-code-examples) Swift, Flutter và React Native sau đây cho biết cách khởi chạy trang liên kết mạng xã hội trên thiết bị iOS.
Thay thế biến String `jwtURL` bằng giá trị trả về từ [endpoint /generateJWT](/apis/profiles/generate-jwt).

#### Swift (iOS)

Trong Swift, sử dụng `UIViewController` và `SFSafariViewControllerDelegate`.
Chúng tôi không khuyến nghị sử dụng `WebView` vì một số mạng xã hội như Facebook và Google chặn xác thực.

#### Flutter (Dart)

Trong Flutter (Dart), không có tương đương trực tiếp với `UIViewController` hoặc `SFSafariViewController`.
Tuy nhiên, bạn có thể đạt được chức năng tương tự bằng cách sử dụng package `url_launcher` để mở các URL web.

#### React Native

React Native cũng không có tương đương trực tiếp với `SFSafariViewController`, nhưng bạn có thể đạt được kết quả tương tự với API `WebBrowser` được cung cấp bởi `expo-web-browser`, mở một URL trong cửa sổ trình duyệt modal chia sẻ cookie với trình duyệt hệ thống. Nếu không, bạn có thể sử dụng hàm `Linking` tích hợp sẵn của React Native để mở Safari: `await Linking.canOpenURL(jwtURL);`

#### Ví dụ mã Mobile

<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 />

Kết hợp với tùy chọn thời gian hết hạn dài hơn, bạn cũng có thể tự động để Ayrshare gửi email cho người dùng của bạn một liên kết đến trang liên kết mạng xã hội.

### Connect Accounts JSON

Ví dụ, JSON sau sẽ gửi email đến `john@user.com` với tên công ty ACME, email liên hệ `support@mycompany.com`, và các liên kết đến điều khoản và chính sách bảo mật:

```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
  }
}
```

Phản hồi sẽ bao gồm nội dung sau nếu email và thời gian hết hạn đã được đặt:

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

### Ví dụ Email JWT Connect Accounts

Đây là một ví dụ về email với liên kết Connect Account mở trang liên kết mạng xã hội:

<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" />

Email sẽ đến từ địa chỉ:

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