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

# Vérification d'identité

> Prévenez l'usurpation d'identité des utilisateurs en exigeant des JWT générés par le serveur pour vérifier les ID d'utilisateur externes, les emails et les abonnements SMS envoyés à OneSignal.

## Aperçu

OneSignal offre une fonctionnalité de sécurité améliorée appelée vérification d'identité pour aider à prévenir l'usurpation d'identité des utilisateurs. Cette fonctionnalité utilise des jetons Web JSON – ou [JWT](https://jwt.io/introduction), générés de manière sécurisée sur votre serveur. Pour vérifier les informations d'abonnement, ces jetons sont transmis à votre application et à l'API de OneSignal.

Activez la vérification d'identité pour sécuriser :

* Connecter les utilisateurs
* Ajouter des abonnements email
* Ajouter des abonnements SMS
* Modifier les identités des utilisateurs

<Warning>
  La vérification d'identité est actuellement en version bêta. Contactez `support@onesignal.com` pour l'activer sur votre compte. Une fois que le support l'a activée, vous l'activez dans votre tableau de bord (voir [Étape 5](#enable-token-identity-verification-in-the-dashboard)).
</Warning>

## Prérequis

* Une application OneSignal existante avec une plateforme push configurée.

* Une application mobile intégrée avec l'un des SDK pris en charge :

  * [OneSignal Android SDK 5.2.0+](https://github.com/OneSignal/OneSignal-Android-SDK/releases)
  * [OneSignal iOS SDK 5.3.0+](https://github.com/OneSignal/OneSignal-iOS-SDK/releases)

<Note>
  La prise en charge des SDK wrapper (Flutter, React Native, Unity, etc.) arrive bientôt.
</Note>

## Configuration

<Steps>
  <Step title="Générer de nouvelles clés">
    Connectez-vous à votre compte OneSignal et accédez à **Paramètres > Clés et ID > Vérification d'identité**.

    <Frame caption="Configuration de la vérification d'identité">
      <img src="https://mintcdn.com/onesignal/Z6xkXGfmy814If53/images/docs/d6f1009-keys_and_ids.png?fit=max&auto=format&n=Z6xkXGfmy814If53&q=85&s=ffc30e4a1f08dcbe4e6a2e4935a7f5de" alt="Settings page showing Keys and IDs with Identity Verification section" width="2420" height="1614" data-path="images/docs/d6f1009-keys_and_ids.png" />
    </Frame>

    Cliquez sur **Générer de nouvelles clés** pour créer une nouvelle paire de clés.

    <Frame caption="Création d'une nouvelle paire de clés">
      <img src="https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/b24c1fd-Identity_Verification.png?fit=max&auto=format&n=56ctKxZSV4m5VEkn&q=85&s=73e56aa60fdef2dc8152bf929ebc1d52" alt="Generate New Keys button in the Identity Verification section" width="2350" height="686" data-path="images/docs/b24c1fd-Identity_Verification.png" />
    </Frame>

    Téléchargez le fichier PEM ou copiez la clé privée, en veillant à stocker la clé privée en toute sécurité.

    <Frame caption="Paire de clés de vérification d'identité">
      <img src="https://mintcdn.com/onesignal/56ctKxZSV4m5VEkn/images/docs/bc217af-id_keys.png?fit=max&auto=format&n=56ctKxZSV4m5VEkn&q=85&s=b8e99ccdb2f4aafd453063540148ca2e" alt="Identity Verification key pair with private key and PEM download" width="1128" height="966" data-path="images/docs/bc217af-id_keys.png" />
    </Frame>

    <Warning>
      Stockez toujours vos clés privées dans un environnement sécurisé, tel qu'un système de gestion de clés. N'exposez jamais les clés privées dans le code côté client, les dépôts publics ou les journaux.
    </Warning>
  </Step>

  <Step title="Générer un JWT de vérification sur votre backend">
    La vérification d'identité nécessite d'authentifier l'utilisateur final avec votre serveur d'authentification **avant** de le connecter à OneSignal. Lorsque l'utilisateur final s'authentifie auprès de votre backend, générez le jeton et incluez-le dans la réponse d'authentification à l'appareil. Si votre application n'exécute pas de serveur backend, envisagez de mettre en place un serveur léger pour vérifier les utilisateurs et générer ces jetons.

    #### Charge utile JWT

    Le JWT peut avoir les propriétés suivantes :

    <ParamField path="iss" required="true">
      Votre ID d'application OneSignal
    </ParamField>

    <ParamField path="exp" required="true">
      La date d'expiration du jeton.
    </ParamField>

    <ParamField path="identity" required="true">
      L'alias de l'utilisateur.
    </ParamField>

    <ParamField path="subscriptions">
      Requis uniquement lors de l'ajout d'abonnements email et SMS à un utilisateur.
    </ParamField>

    #### Signature du JWT

    Signez le JWT en utilisant l'algorithme ES256. Assurez-vous que votre backend est configuré pour utiliser cette méthode de signature afin d'éviter les problèmes de vérification lors de l'envoi du JWT à OneSignal. Nous recommandons une [bibliothèque JWT](https://jwt.io/libraries) pour ce faire.

    Exemple utilisant [jsonwebtoken](https://www.npmjs.com/package/jsonwebtoken) :

    <CodeGroup>
      ```typescript Node.js theme={null}
      import jwt from 'jsonwebtoken';

      const APP_ID = process.env['ONESIGNAL_APP_ID']
      const IDENTITY_VERIFICATION_SECRET = process.env['ONESIGNAL_IDENTITY_VERIFICATION_SECRET_KEY']

      // Generates JWT, potentially with subscription claims, for the user identified by the External ID
      function signOneSignalJWT(externalId, subscriptions) {
      return jwt.sign({
      iss: APP_ID,
      exp: Math.floor(Date.now() / 1000) + 3600, // 1-hour expiration
      identity: {
      'external_id': externalId,
      },
      subscriptions
      },
      IDENTITY_VERIFICATION_SECRET,
      { algorithm: 'ES256' });
      }

      // Pass this token to your mobile app to use with the `login` SDK method
      const onesignalJWT = signOneSignalJWT('EXTERNAL_ID');

      ```
    </CodeGroup>

    La clé privée se trouve dans le fichier de l'étape précédente que nous avons téléchargé depuis le tableau de bord.

    #### Vérifier votre JWT

    Avant d'intégrer avec le SDK, vérifiez que votre JWT est correctement généré en démarrant votre serveur et en appelant l'endpoint :

    <CodeGroup>
      ```typescript Node.js theme={null}
        node server.js
      ```
    </CodeGroup>

    <CodeGroup>
      ```bash cURL theme={null}
        curl http://localhost:3000/generate-jwt/your-external-id
      ```
    </CodeGroup>

    Vous devriez recevoir une réponse comme :

    ```json theme={null}
    {
      "jwt": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9..."
    }
    ```

    Collez la valeur JWT sur [jwt.io](https://jwt.io) et confirmez que la charge utile décodée contient les paramètres suivants :

    ```json theme={null}
    {
      "iss": "your-onesignal-app-id",
      "exp": 1234567890,
      "identity": {
        "external_id": "your-external-id"
      }
    }
    ```

    Confirmez les éléments suivants avant de passer à l'étape suivante :

    * `iss` correspond à votre ID d'application OneSignal dans **Paramètres > Clés et ID**
    * `identity.external_id` est présent et correspond à la valeur que vous passerez à `OneSignal.login()`
    * `exp` est un horodatage futur — un jeton expiré sera rejeté par OneSignal

    #### Inclusion des abonnements

    Idéalement, les détails d'abonnement, tels que l'email ou le numéro de téléphone, sont inclus dans la charge utile JWT lors de la connexion d'un utilisateur. Si ces détails ne sont pas disponibles au départ, votre serveur de vérification doit fournir un endpoint pour générer des jetons dynamiquement à mesure que les informations d'abonnement deviennent disponibles.

    Exemple : Génération de JWT pour ajouter des abonnements

    <CodeGroup>
      ```typescript Node.js theme={null}
      const subscriptions = [
        {
            "type": "Email",
            "token": "[email protected]"
        },
        {
            "type": "SMS",
            "token": "+12345678"
        }
      ]
      const onesignalJWT = signOneSignalJWT('EXTERNAL_ID', subscriptions)
      ```
    </CodeGroup>
  </Step>

  <Step title="Transmettre le JWT à la méthode `login`">
    Une fois que votre backend génère le JWT, appelez la méthode `login` avec celui-ci. Ce jeton garantit que l'identité de l'utilisateur est vérifiée avant que des modifications, telles que l'ajout d'un abonnement email ou SMS, puissent être effectuées.

    Exemple de connexion :

    <CodeGroup>
      ```java java theme={null}
      String externalId = "YOUR_EXTERNAL_ID";
      String onesignalJWT = "YOUR_JWT_TOKEN";

      OneSignal.login(externalId, onesignalJWT);
      ```

      ```kotlin kotlin theme={null}
      val externalId = "YOUR_EXTERNAL_ID"
      val onesignalJWT = "YOUR_JWT_TOKEN"

      OneSignal.login(externalId, onesignalJWT)
      ```

      ```swift Swift theme={null}
      let externalId = "YOUR_EXTERNAL_ID"
      let onesignalJWT = "YOUR_JWT_TOKEN"

      OneSignal.login(externalId: externalId, token: onesignalJWT)
      ```

      ```c objective-c theme={null}
      NSString* externalId = @"YOUR_EXTERNAL_ID";
      NSString* onesignalJWT = @"YOUR_JWT_TOKEN";

      [OneSignal login:externalId withToken:onesignalJWT];
      ```
    </CodeGroup>
  </Step>

  <Step title="Gérer les événements du cycle de vie JWT">
    Vous devrez implémenter un endpoint dédié sur votre backend pour gérer des scénarios tels que l'invalidation de jetons. Cet endpoint doit fournir un JWT actualisé lorsque OneSignal demande une mise à jour.

    Exemple de gestion de l'invalidation de jeton et de rafraîchissement du JWT :

    <CodeGroup>
      ```java java theme={null}
      OneSignal.addUserJwtInvalidatedListener(event -> {
        // Get the expired user's External ID
        String externalId = event.getExternalId();

        // Fetch a new JWT from your backend for the user
        String onesignalJWT = "yourUpdatedToken";

        // Provide the new JWT to the SDK
        OneSignal.updateUserJwt(externalId, onesignalJWT);
      });
      ```

      ```kotlin kotlin theme={null}
      OneSignal.addUserJwtInvalidatedListener(
         object : IUserJwtInvalidatedListener {
             override fun onUserJwtInvalidated(event: UserJwtInvalidatedEvent) {
               val externalId = event.externalId
               val onesignalJWT = ""
               updateUserJwt(externalId, onesignalJWT)
             }
         },
      )
      ```

      ```swift Swift theme={null}
      class AppDelegate: UIResponder, UIApplicationDelegate, OSUserJwtInvalidatedListener {
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
          // Set self to listen for JWT invalidated events
          OneSignal.addUserJwtInvalidatedListener(self)

          // Remove the JWT listener as needed by calling:
          // `OneSignal.removeUserJwtInvalidatedListener(self)`
        }

        // Required to conform to `OSUserJwtInvalidatedListener` protocol
        func onUserJwtInvalidated(event: OneSignalUser.OSUserJwtInvalidatedEvent) {
          // Get the expired user's External ID
          let externalId = event.externalId

          // Fetch a new JWT from your backend for the user
          let onesignalJWT = "yourUpdatedToken"

          // Provide the new JWT to the SDK
          OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)
        }
      }
      ```

      ```c objective-c theme={null}
      @interface MyListener: NSObject<OSUserJwtInvalidatedListener>
      @end

      @implementation MyListener
      - (void)onUserJwtInvalidatedWithEvent:(OSUserJwtInvalidatedEvent * _Nonnull)event {
        // Get the expired user's External ID
        NSString *externalId = event.externalId;

        // Fetch a new JWT from your backend for the user
        NSString *onesignalJWT = @"yourUpdatedToken";

        // Provide the new JWT to the SDK
      	[OneSignal updateUserJwt:externalId withToken:onesignalJWT];
      }

      // Add or remove your User Jwt Invalidated Listener
      [OneSignal addUserJwtInvalidatedListener:myListener];
      [OneSignal removeUserJwtInvalidatedListener:myListener];
      ```
    </CodeGroup>

    Cela garantit que lorsque le JWT d'un utilisateur est invalidé, un nouveau peut être récupéré depuis votre backend et transmis à OneSignal. Vous pouvez également utiliser cette fonction pour générer un jeton avec un email et un numéro de téléphone, vous permettant de gérer les abonnements email et SMS si le jeton créé lors de l'authentification ne les contient pas.
  </Step>

  <Step title="Activer la vérification d'identité par jeton dans le tableau de bord">
    Dans **Paramètres > Clés et ID**, activez **Vérification d'identité par jeton**.

    <Frame caption="Activation de la vérification d'identité par jeton">
      <img src="https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/4887367-identity_verification_enabled.png?fit=max&auto=format&n=YOTSrtBSoqdrJ37A&q=85&s=26d06ca0a008e841d5206093bfbf2a8c" alt="Token Identity Verification toggle enabled in dashboard settings" width="2350" height="686" data-path="images/docs/4887367-identity_verification_enabled.png" />
    </Frame>

    Une fois activée, votre application doit envoyer des JWT OneSignal pour vérifier l'authenticité de l'abonnement. De plus, votre application est tenue d'appeler la méthode `login` en utilisant un JWT généré par votre serveur de jetons de vérification d'identité.
  </Step>
</Steps>

## Ajout d'abonnements

Vous n'avez pas besoin de prendre de mesures supplémentaires pour ajouter des abonnements depuis votre application mobile ; l'appel de la méthode login le gère automatiquement pour vous.

<Tabs>
  <Tab title="Ajouter un email">
    <CodeGroup>
      ```java java theme={null}
      OneSignal.getUser().addEmail(emailAddress);
      ```

      ```kotlin kotlin theme={null}
      OneSignal.getUser().addEmail(emailAddress)
      ```

      ```swift Swift theme={null}
      // If you have not already included it in your JWT token, update the JWT with the email
      let onesignalJWT = "newTokenThatContainsTheEmailToAdd"
      OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)

      // Add the email
      OneSignal.User.addEmail(emailAddress)
      ```

      ```c objective-c theme={null}
      // If you have not already included it in your JWT token, update the JWT with the email
      NSString *onesignalJWT = @"newTokenThatContainsTheEmailToAdd";
      [OneSignal updateUserJwt:externalId withToken:onesignalJWT];

      // Add the email
      [OneSignal.User addEmail:emailAddress];
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Ajouter un numéro de téléphone">
    <CodeGroup>
      ```java java theme={null}
      OneSignal.getUser().addSms(smsNumber);
      ```

      ```kotlin kotlin theme={null}
      OneSignal.getUser().addSms(smsNumber)
      ```

      ```swift Swift theme={null}
      // If you have not already included it in your JWT token, update the JWT with the sms
      let onesignalJWT = "newTokenThatContainsTheSmsToAdd"
      OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)

      // Add the sms number
      OneSignal.User.addSms(smsNumber)
      ```

      ```c objective-c theme={null}
      // If you have not already included it in your JWT token, update the JWT with the sms
      NSString *onesignalJWT = @"newTokenThatContainsTheSmsToAdd";
      [OneSignal updateUserJwt:externalId withToken:onesignalJWT];

      // Add the sms number
      [OneSignal.User addSms:smsNumber];
      ```
    </CodeGroup>
  </Tab>
</Tabs>

***

## API REST

Lorsque la vérification d'identité par jeton est activée, toutes les requêtes vers les API suivantes doivent inclure un JWT généré par le serveur dans les en-têtes en tant que jeton porteur, par exemple, `Authorization: Bearer <JWT>`.

* [Créer un utilisateur](/reference/create-user)
* [Voir un utilisateur](/reference/view-user)
* [Mettre à jour un utilisateur](/reference/update-user)
* [Supprimer un utilisateur](/reference/delete-user)
* [Voir l'identité de l'utilisateur](/reference/fetch-aliases)
* [Créer un alias](/reference/create-alias)
* [Supprimer un alias](/reference/delete-alias)
* [Créer un abonnement](/reference/create-subscription)
* [Mettre à jour un abonnement](/reference/update-subscription)

***

## FAQ

### La vérification d'identité est-elle obligatoire ?

Non, mais elle est fortement recommandée. Sans elle, tout client connaissant l'ID d'utilisateur externe d'un utilisateur peut usurper son identité et modifier ses abonnements ou ses données.

### Que se passe-t-il si le JWT expire pendant une session ?

Le SDK déclenche un événement d'invalidation de JWT. Implémentez `addUserJwtInvalidatedListener` (voir [Gérer les événements du cycle de vie JWT](#handle-jwt-lifecycle-events)) pour récupérer un jeton mis à jour depuis votre backend et le transmettre à `updateUserJwt`.

### Quels SDK prennent en charge la vérification d'identité ?

Actuellement, le SDK Android natif (5.2.0+) et le SDK iOS (5.3.0+). La prise en charge des SDK wrapper (Flutter, React Native, Unity, etc.) arrive bientôt.

### Ai-je besoin de la vérification d'identité pour l'API REST ?

Lorsque la vérification d'identité par jeton est activée, toutes les requêtes vers les [API prises en charge](#rest-api) doivent inclure un JWT généré par le serveur en tant que jeton porteur dans l'en-tête `Authorization`. Le JWT est généré de la même manière que pour l'utilisation du SDK.

### Quel algorithme le JWT utilise-t-il ?

La vérification d'identité requiert des JWT signés avec l'algorithme **ES256** (ECDSA utilisant P-256 et SHA-256). Les autres algorithmes seront rejetés.

***
