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.
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, 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
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).
Connectez-vous à votre compte OneSignal et accédez à Paramètres > Clés et ID > Vérification d’identité.
Configuration de la vérification d'identité
Cliquez sur Générer de nouvelles clés pour créer une nouvelle paire de clés.
Création d'une nouvelle paire de clés
Téléchargez le fichier PEM ou copiez la clé privée, en veillant à stocker la clé privée en toute sécurité.
Paire de clés de vérification d'identité
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.
2
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.
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 pour ce faire.Exemple utilisant jsonwebtoken :
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 IDfunction signOneSignalJWT(externalId, subscriptions) {return jwt.sign({iss: APP_ID,exp: Math.floor(Date.now() / 1000) + 3600, // 1-hour expirationidentity: {'external_id': externalId,},subscriptions},IDENTITY_VERIFICATION_SECRET,{ algorithm: 'ES256' });}// Pass this token to your mobile app to use with the `login` SDK methodconst onesignalJWT = signOneSignalJWT('EXTERNAL_ID');
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.
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
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 :
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 :
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);});
OneSignal.addUserJwtInvalidatedListener( object : IUserJwtInvalidatedListener { override fun onUserJwtInvalidated(event: UserJwtInvalidatedEvent) { val externalId = event.externalId val onesignalJWT = "" updateUserJwt(externalId, onesignalJWT) } },)
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) }}
@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];
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.
5
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.
Activation de la vérification d'identité par jeton
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é.
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.
Ajouter un email
Ajouter un numéro de téléphone
OneSignal.getUser().addEmail(emailAddress);
OneSignal.getUser().addEmail(emailAddress)
// If you have not already included it in your JWT token, update the JWT with the emaillet onesignalJWT = "newTokenThatContainsTheEmailToAdd"OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)// Add the emailOneSignal.User.addEmail(emailAddress)
// If you have not already included it in your JWT token, update the JWT with the emailNSString *onesignalJWT = @"newTokenThatContainsTheEmailToAdd";[OneSignal updateUserJwt:externalId withToken:onesignalJWT];// Add the email[OneSignal.User addEmail:emailAddress];
OneSignal.getUser().addSms(smsNumber);
OneSignal.getUser().addSms(smsNumber)
// If you have not already included it in your JWT token, update the JWT with the smslet onesignalJWT = "newTokenThatContainsTheSmsToAdd"OneSignal.updateUserJwt(externalId: externalId, token: onesignalJWT)// Add the sms numberOneSignal.User.addSms(smsNumber)
// If you have not already included it in your JWT token, update the JWT with the smsNSString *onesignalJWT = @"newTokenThatContainsTheSmsToAdd";[OneSignal updateUserJwt:externalId withToken:onesignalJWT];// Add the sms number[OneSignal.User addSms:smsNumber];
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>.
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) 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 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.