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

# Visión general de Generate JWT

> Genera una URL de vinculación de red social para un 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} />

El [endpoint generateJWT](/apis/profiles/generate-jwt) genera una URL de vinculación de red social para un único User Profile.
Consulta la [integración de API para Business Plan y Launch Plan](/multiple-users/api-integration-business) para más detalles.

## Cambiar de perfil

Para cambiar entre distintas sesiones de perfil (por ejemplo, cuando se prueba con varios perfiles), primero necesitas cerrar la sesión del perfil actual. Consulta [Cierre de sesión automático de una sesión de perfil](/multiple-users/api-integration-business#automatic-logout-of-a-profile-session) para instrucciones sobre cómo gestionar correctamente el cambio de perfil.

## Private Key y Profile Key

### Dónde obtener la Private Key

El archivo Private Key (private.key) y un archivo JSON de ejemplo para Postman se incluyen con tu [Integration Package](/multiple-users/api-integration-business#integration-package) recibido durante el onboarding.
El Integration Package también puede obtenerse en el dashboard de desarrolladores de Ayrshare en la página de API -> Integration Package.

### Uso de la Private Key

Recomendamos leer la Private Key private.key desde un archivo y enviarla como cadena en el campo `privateKey`, lo que te permite preservar todos los caracteres, incluidos los saltos de línea.
La Private Key debe ser exacta, es decir, deben conservarse todos los caracteres, incluidos los saltos de línea.
Si pegas la clave directamente en tu código, es posible que debas reemplazar manualmente los saltos de línea con un carácter `\n` o codificar la cadena como URL.

Pegar la clave directamente en el código suele causar problemas.

## Generar un JSON Web Token

Vídeo de 1 minuto que explica cómo generar un 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>

La URL del JWT es válida durante **5 minutos**. Pasados 5 minutos deberás generar una nueva URL de JWT.
Consulta [Max Pack `expiresIn`](/apis/profiles/generate-jwt-overview#jwt-expires-in) para opciones adicionales.

## Abrir la URL del JWT

Abre la URL del JWT en una nueva pestaña del navegador, una nueva ventana del navegador o un View Controller en iOS.

Puedes controlar el [cierre o la redirección](/multiple-users/api-integration-business#opening-and-closing-the-social-linking-url) de la nueva ventana o pestaña.

<Note>
  Las redes sociales no permiten abrir la URL en un iFrame ni ofuscar el dominio de origen del partner
  autorizado profile.ayrshare.com.
</Note>

## Verificar la URL del JWT

El endpoint `generateJWT` no valida la URL del JWT devuelta de forma predeterminada.
Por ejemplo, si se pasa una Private Key corrupta a `generateJWT`, se devolverá una URL igualmente, pero esa URL resultará en un error 401.

Puedes verificar la URL del JWT devuelta incluyendo `verify: true` en los parámetros del cuerpo de `generateJWT`. Si la URL del JWT no se puede validar, se devolverá un error. Por ejemplo, si a la Private Key le faltara un carácter, se devolvería lo siguiente:

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

Recomendamos usar `verify: true` solo en entornos que no sean de producción, ya que la validación requiere tiempo de procesamiento adicional.

## Pruebas en Postman

Se **recomienda** probar primero la creación de la URL del JWT en [Postman](/testing/postman).
Incluido en el Integration Package, disponible en la página API Key del Primary Profile del dashboard, hay un archivo JSON de configuración de ejemplo para Postman que contiene todo lo necesario para verificar la creación de la URL del JWT.
Solo tienes que importar el archivo de configuración en Postman, rellenar tu Profile Key (que se encuentra en el dashboard de desarrolladores de Ayrshare cambiando al perfil que quieras probar) en el campo `profileKey` del *body*, y pulsar el botón azul *Send*.
Todos los demás campos obligatorios ya están rellenos.

También puedes [generar el código desde Postman](/testing/postman#auto-generate-api-code-with-postman) o leer el archivo de clave desde un directorio o una base de datos.

## Método de vinculación de Instagram

Las cuentas de Instagram pueden vincularse de [dos maneras](/dashboard/connect-social-accounts/instagram): directamente con **Instagram Login**, o a través de una **Facebook Page conectada**.
El flujo que se inicia cuando un usuario hace clic en el botón de Instagram en la página de vinculación de redes sociales suele estar controlado por el ajuste global de la cuenta [Instagram Login](/multiple-users/manage-user-profiles#instagram-login) en el dashboard.

El parámetro `instagramLinkMethod` del cuerpo del [endpoint generateJWT](/apis/profiles/generate-jwt) te permite sobrescribir ese ajuste para una única URL de vinculación:

| Valor       | Flujo de vinculación de Instagram                    |
| ----------- | ---------------------------------------------------- |
| `instagram` | Instagram Login directo. No requiere Facebook Page.  |
| `facebook`  | Vinculación a través de una Facebook Page conectada. |

Por ejemplo, si el valor predeterminado de tu cuenta es la vinculación mediante Facebook Page, lo siguiente fuerza el Instagram Login directo solo para esta sesión de vinculación:

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

La URL del JWT generada incluirá la sobrescritura, y al hacer clic en el botón de Instagram en la página de vinculación se iniciará el flujo solicitado durante toda la sesión, incluyendo la redirección de autorización de Instagram/Facebook.

Algunas cosas que debes saber:

* La sobrescritura solo se aplica a la página de vinculación abierta desde la URL devuelta. No cambia el ajuste global de Instagram Login de tu cuenta ni afecta a otras sesiones de vinculación.
* Si se omite `instagramLinkMethod`, la página de vinculación utiliza el ajuste global de tu cuenta, exactamente como antes.
* Si se envía un valor no válido, se devuelve un error `400` con los valores válidos (`instagram`, `facebook`).
* Revisa las [diferencias de funcionalidad](/multiple-users/manage-user-profiles#direct-instagram-login-vs-facebook-page-authentication) entre los dos flujos antes de elegir una sobrescritura: algunas funcionalidades de Instagram, como la búsqueda por hashtags y las colaboraciones, solo están disponibles con la autenticación mediante Facebook Page.

## JWT Expires In

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

Si deseas un tiempo de expiración del JWT mayor que los 5 minutos por defecto, incluye el campo `expiresIn`.

Por ejemplo, envía el siguiente JSON para que la URL del JWT sea válida durante 30 minutos:

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

Esto te permite [enviar el enlace por correo](/apis/profiles/generate-jwt-overview#connect-accounts-email) a tus usuarios en lugar de que tengan que acceder a tu aplicación o plataforma.
Un caso de uso habitual es cuando tu usuario necesita reconectar una cuenta social: puedes enviarle por correo el enlace del JWT para volver a vincular directamente la cuenta social sin tener que navegar hasta tu plataforma.

<Warning>
  Asegúrate de revisar con tu equipo de seguridad durante cuánto tiempo tu empresa desea mantener activo el JWT.
  Tiempos de expiración más largos crean un riesgo adicional de que una parte no autorizada acceda al enlace.
</Warning>

## Integraciones

### Bubble.io JWT

Si eres usuario de Bubble, consulta *Generate JWT Token* en la sección Bubble.io para las instrucciones:

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

### Mobile JWT

Los siguientes [ejemplos de código móvil](/apis/profiles/generate-jwt-overview#mobile-code-examples) en Swift, Flutter y React Native muestran cómo lanzar la página de vinculación de redes sociales en un dispositivo iOS.
Reemplaza la variable de tipo String `jwtURL` con el valor devuelto por el [endpoint /generateJWT](/apis/profiles/generate-jwt).

#### Swift (iOS)

En Swift, utiliza un `UIViewController` y `SFSafariViewControllerDelegate`.
No recomendamos usar un `WebView`, ya que algunas redes sociales como Facebook y Google bloquean la autenticación.

#### Flutter (Dart)

En Flutter (Dart) no hay un equivalente directo a `UIViewController` o `SFSafariViewController`.
Sin embargo, puedes conseguir una funcionalidad similar usando el paquete `url_launcher` para abrir URLs web.

#### React Native

React Native tampoco tiene un equivalente directo a `SFSafariViewController`, pero puedes conseguir un resultado similar con la API `WebBrowser` que ofrece `expo-web-browser`, que abre una URL en una ventana modal de navegador que comparte cookies con el navegador del sistema. Como alternativa, puedes usar la función `Linking` integrada de React Native para abrir Safari: `await Linking.canOpenURL(jwtURL);`

#### Ejemplos de código móvil

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

Junto con la opción de tiempo de expiración más largo, también puedes hacer que Ayrshare envíe automáticamente por correo a tus usuarios un enlace a la página de vinculación de cuentas sociales.

### Connect Accounts JSON

Por ejemplo, el siguiente JSON enviará un correo a `john@user.com` con el nombre de empresa ACME, el correo de contacto `support@mycompany.com` y enlaces a los términos y la política de privacidad:

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

La respuesta incluirá lo siguiente si se configuraron el correo y el tiempo de expiración:

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

### Ejemplo de correo de Connect Accounts para JWT

Este es un ejemplo de un correo con el enlace Connect Account que abre la página de vinculación de cuentas sociales:

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

El correo se enviará desde la dirección:

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