Overview
JWT (JSON Web Token) authentication is a standard method for securely verifying user identity. By implementing JWT authentication, you add a critical layer of security to your data collection process with MoEngage.
The feature ensures that the data sent on behalf of your identified users is authentic and has not been tampered with. This security is achieved by requiring a token that is cryptographically signed by your own server, which prevents unauthorized users from impersonating your legitimate users.
| library_add_check |
Prerequisites Before you begin the implementation, please ensure you meet the following requirements:
|
The following diagram illustrates the interaction between your application, your
server, the MoEngage SDK, and the MoEngage server:
Integration
Follow these steps to integrate JWT authentication into your iOS application.
Step 1: Enable JWT Authentication
You can enable JWT authentication during SDK initialization by configuring the networkConfig.authorizationConfig property on the MoEngageSDKConfig object.
let sdkConfig = MoEngageSDKConfig(appId: "", dataCenter: .YOUR_DATA_CENTER)
sdkConfig.networkConfig = MoEngageNetworkRequestConfig(authorizationConfig: MoEngageNetworkAuthorizationConfig(isJwtEnabled: true))
#if DEBUG
MoEngage.sharedInstance.initializeDefaultTestInstance(sdkConfig)
#else
MoEngage.sharedInstance.initializeDefaultLiveInstance(sdkConfig)
#endif
MoEngageSDKConfig* sdkConfig = [[MoEngageSDKConfig alloc] initWithAppId:@"" dataCenter:YOUR_DATA_CENTER];
sdkConfig.networkConfig = [[MoEngageNetworkRequestConfig alloc] initWithAuthorizationConfig:[[MoEngageNetworkAuthorizationConfig alloc] initWithIsJwtEnabled:YES]];
#ifdef DEBUG
[[MoEngage sharedInstance] initializeDefaultTestInstance:sdkConfig];
#else
[[MoEngage sharedInstance] initializeDefaultLiveInstance:sdkConfig];
#endif
Step 2: Pass the JWT to the SDK
Your application is responsible for managing the JWT lifecycle. The recommended flow is to fetch a token upon user login and pass the token to the SDK. You should also check if the token has expired on subsequent app launches and fetch a new one if necessary.
Use the MoEngageSDKCore.passAuthenticationDetails() method to provide the token to the SDK.
let jwtDetails = MoEngageJwtAuthenticationDetails(token: "your_jwt_token", identifier: "user_id")
MoEngageSDKCore.sharedInstance.passAuthenticationDetails(jwtDetails)
MoEngageJwtAuthenticationDetails* jwtDetails = [[MoEngageJwtAuthenticationDetails alloc] initWithToken:@"your_jwt_token" identifier:@"user_id"];
[[MoEngageSDKCore sharedInstance] passAuthenticationDetails:jwtDetails];
Step 3: Handle Authentication Errors
To handle token validation errors that the MoEngage server returns, you must register an error listener using MoEngageSDKCore.registerAuthenticationListener() method. The SDK invokes this listener when an authentication error occurs, which allows your application to fetch and provide a new token.
class JwtAuthenticationListener: NSObject, MoEngageAuthenticationError.Listener {
func onError(_ error: MoEngageAuthenticationError) {
print("Authentication Error Received:")
if let jwtError = error as? MoEngageJwtAuthenticationError {
print("- Code: \(jwtError.details.code.rawValue) - \(jwtError.details.code.description)")
print("- Token: \(jwtError.details.token == nil ? "No token" : String(jwtError.details.token!.prefix(20)) + "...")")
print("- Identifier: \(jwtError.details.identifier == nil ? "No identifier" : jwtError.details.identifier!)")
print("- Message: \(jwtError.details.message ?? "No message")")
} else {
print("- Message: \(error.details.message ?? "No message")")
}
print("- Account: \(error.accountMeta.appID)")
}
}
// Register listner after SDK initialization
let listener = JwtAuthenticationListener()
MoEngageSDKCore.sharedInstance.registerAuthenticationListener(listener)
@interface JwtAuthenticationListener : NSObject
@end
@implementation JwtAuthenticationListener
- (void)onError:(MoEngageAuthenticationError *)error {
NSLog(@"Authentication Error Received:");
if ([error isKindOfClass:[MoEngageJwtAuthenticationError class]]) {
MoEngageJwtAuthenticationError *jwtError = (MoEngageJwtAuthenticationError *)error;
NSLog(@"- Code: %ld - %@", (long)jwtError.details.code.rawValue, jwtError.details.code.description);
NSString *tokenDisplay = jwtError.details.token ?
[[jwtError.details.token substringToIndex:MIN(20, jwtError.details.token.length)] stringByAppendingString:@"..."] :
@"No token";
NSLog(@"- Token: %@", tokenDisplay);
NSLog(@"- Identifier: %@", jwtError.details.identifier ?: @"No identifier");
NSLog(@"- Message: %@", jwtError.details.message ?: @"No message");
} else {
NSLog(@"- Message: %@", error.details.message ?: @"No message");
}
NSLog(@"- Account: %@", error.accountMeta.appID);
}
@end
//
JwtAuthenticationListener *listener = [[JwtAuthenticationListener alloc] init];
[[MoEngageSDKCore sharedInstance] registerAuthenticationListener:listener];
Step 4: Register the listener after SDK initialization
Register the MoEngageAuthenticationError.Listener in a global scope, such as the applicaton(_:didFinishLaunchingWithOptions:) method of your AppDelegate class, to ensure your application always receives callbacks.
let listener = JwtAuthenticationListener()
MoEngageSDKCore.sharedInstance.registerAuthenticationListener(listener)
JwtAuthenticationListener *listener = [[JwtAuthenticationListener alloc] init];
[[MoEngageSDKCore sharedInstance] registerAuthenticationListener:listener];
| info |
Information
|