End User Authentication

Learn about authentication methods and JWT generation

Authentication is achieved in the Brand Messenger Legacy iOS SDK using a JSON Web Token (JWT) and a unique User ID.

The JWT consists of a header, payload, and signature. It's generated using your App Key ID and App Key Secret. Both of these are obtained by contacting Khoros Support, if you do not already have them, and should be kept completely hidden from your users.

📘

We recommend reviewing your JWT generation method with your IT department to ensure that you are using the most secure option possible.

Generate the JWT

The following example Swift snippet generates a JWT using an open-source library (JSONWebToken) where:

  • API_KEY_ID is your API Key ID
  • API_KEY_SECRET is your API Key Secret
  • userId is the user's ID in your system of record
let someDateTime = Date(timeIntervalSince1970: TIME_IN_MILLISECONDS)
var claims = ClaimSet()
claims.issuedAt = someDateTime
claims["userId"] = userID
claims["scope"] = "appUser"
claims["platform"] = "ios"
claims["givenName"] = loginName

var header = [String: String]()
header["kid"] = API_KEY_ID
header["typ"] = "JWT"

let jwtToken = JWT.encode(
    claims: claims,
    algorithm: .hs256(API_KEY_SECRET.data(using: .utf8)!),
    headers: header)

📘

JSONWebToken is available on Cocoapods and can be installed using the following:

pod 'JSONWebToken'

Using an identity provider (IdP)

Companies that opt to use an IdP should be aware of the general authentication flow and how the login process works for accounts using an IdP for authentication. Here is a quick walkthrough of the flow:

  • The user logs into the IdP.
  • The IdP returns the userId and name
  • The app calls the company's API getJWT with userId and name
  • The API generates the JWT in the server and returns it to the app
  • The app logs into Brand Messenger using JWT. Since the JWT includes the userId and name, the user can be identified between sessions/devices/etc.

🚧

Even with the use of an IdP, it's important that the JWT is generated at the server, rather than the app. This prevents any potential security risks that arise from storing the API_KEY_SECRET locally within the app's code.

During JWT token generation, include the following information in your claims:

  • 'userId' as the userId from your IdP
  • 'scope' as 'appUser'
  • 'platform' as 'ios'
  • givenName' as user's name`

The header should include:

  • kid as your API Key ID
  • typ as JWT

The token should be signed with the HS256 algorithm using UTF-8 encoding of your API Key Secret.

End User Login

Finally, the login process completes with userID and JWT token.

BrandMessenger.login(userID, jwt: jwtToken) { ( error:Error? , userInfo:[AnyHashable : Any]?) in
    
}

Once successful, Brand Messenger Legacy SDK is ready to communicate.

Reauthentication

The SDK can set a callback delegate for when an API fails due to authentication errors such as an expired JWT token.

Set KBMSettings's authenticationDelegate during SDK initialization. Eg, when initializing in AppDelegate and setting authenticationDelegate to self:

let settings = KBMSettings(integrationId: smoochIntegrationId)
settings.authenticationDelegate = self

BrandMessenger.initWith(settings) { (error: Error?, userInfo: [AnyHashable : Any]?) in }

Implement KBMAuthenticationDelegate in the class, add the onInvalidToken method and fix the authentication. Eg, when setting AppDelegate as delegate:

extension AppDelegate : KBMAuthenticationDelegate {
    func onInvalidToken(_ error: Error, handler completionHandler: @escaping KBMAuthenticationCompletionBlock) {
        // get a new jwt token and re-login
        let jwtString = getJWT()
        completionHandler(jwtString)
    }
}

Re-authenticating on Conversation screen

During re-authentication, connections and references to the conversation are recreated. Conversation screen displayed via BrandMessenger.show() needs to be recreated and displayed, or reconnected with BrandMessenger.reloadShownConversationViewController after successful re-authentication, if it is on display during re-authentication.
EG:

if let vc = self.presentedViewController {
    BrandMessenger.reloadShownConversationViewController(vc)
}