Authenticating Users

If your software or application has an existing user authentication method then you can optionally federate those identities with Sunshine Conversations by issuing a JSON web token (JWT). A JWT is required to protect the identity and data of these users. This option requires your app to be connected to your own secure web service. There are JWT libraries available supporting a wide variety of popular languages and platforms.

First, you must assign an externalId to each of your users. The externalId will uniquely identify your users within Sunshine Conversations and the JWTs you issue serve as a signed proof that your software or app has successfully authenticated that user.

To log in with a JWT:

  1. Generate an API key for your Sunshine Conversations app. You can do this from the Sunshine Conversations dashboard under the Settings tab.

    If you are a licensed Zendesk customer, you can generate an API key from the Zendesk Admin Center. See Using the Conversations API dashboard for more information.

  2. Implement server side code to sign new JWTs using the key ID and secret provided. The JWT header must specify the key ID (kid). The JWT payload must include a scope claim of user and an external_id claim which is the externalId that you assigned to the user. Make sure the external_id field is formatted as a String. If you use numeric ids, the external_id must be a String representation of the number - using a number directly will result in an invalid auth error.

    A node.js sample is provided below using jsonwebtoken >= 6.0.0

    var jwt = require('jsonwebtoken');
    var KEY_ID = 'app_5deaa3531c7f940010cc4ba4';
    var SECRET = 'BFJJ88naxc5PZNAMU9KpBNTR';
    
    var signJwt = function(userId) {
        return jwt.sign(
            {
                scope: 'user',
                external_id: userId
            },
            SECRET,
            {
                header: {
                    alg: 'HS256',
                    typ: 'JWT',
                    kid: KEY_ID
                }
            }
        );
    };
    
  3. Issue a JWT for each user. You should tie-in the generation and delivery of this JWT with any existing user login process used by your app.

  4. Initialize Sunshine Conversations in your website or app. See instructions for Web, iOS and Android.

  5. Call Smooch.login with your externalId and jwt:

    Web (JavaScript):

    Smooch.login('external-id', 'jwt').then(
        function() {
            // Your code after login is complete
        },
        function(err) {
            // Something went wrong during login. Your JWT might be invalid
        }
    );
    

    iOS (Objective-C):

    [Smooch login:@"external-id" jwt:@"jwt" completionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable userInfo) {
        if (error == nil) {
            // Your code after login is complete
        } else {
            // Something went wrong during login. Your JWT might be invalid
        }
    }];
    

    iOS (Swift):

    Smooch.login("external-id", jwt:"jwt") { ( error:Error? , userInfo:[AnyHashable : Any]?) in
        if (error == nil) {
            // Your code after login is complete
        } else {
            // Something went wrong during login. Your JWT might be invalid
        }
    }
    

    Android (Java):

    Smooch.login("external-id", "jwt", new SmoochCallback() {
        @Override
        public void run(Response response) {
            if (response.getError() == null) {
                // Your code after login is complete
            } else {
                // Something went wrong during login. Your JWT might be invalid
            }
        }
    });
    

Expiring JWTs on SDKs

If you desire to generate credentials that expire after a certain amount of time, using JWTs is a good way to achieve this.

The exp (expiration time) property of a JWT payload is honoured by the Sunshine Conversations API. A request made with a JWT which has an exp that is in the past will be rejected.

Keep in mind that using JWTs with exp means that you will need to implement regeneration of JWTs, which demands additional logic (Android, iOS or Web Messenger) in your software.

JWTs are required to identify your users by a custom identifier (externalId) in SDKs. In this case, JWTs are signed with an app API key with a scope of appUser, and an additional payload property userId.

Sample JWT Structure with expiry

Header

{
    "alg": "HS256",
    "typ": "JWT",
    "kid": "<app-key-id>"
}

Payload

{
    "scope": "user",
    "exp": "1542499200", // unix timestamp representating 2018-11-18T00:00:00+00:00
    "external_id": "<user-id>"
}

Users on multiple clients

You may have a single user logging in as the same externalId from multiple clients. For example, they have your app installed on both their iPhone and their iPad. You might also have Sunshine Conversations integrated in both your mobile app as well as on your web site.

Once a user has been logged in to Sunshine Conversations, they will see the same conversation across each of these clients.

Omitting the externalId

Sunshine Conversations will work perfectly fine without an externalId. Profile information can still be included, and the user can take advantage of all rich messaging features, but the user will only be able to access the conversation from the client they’re currently using. Without an externalId, if the same individual opens Sunshine Conversations on a new client, or runs your web app in an incognito browser session, they will see a newly created empty conversation when they open Sunshine Conversations, and on the business side they will be represented as two distinct users. This will happen even if you specify the same profile information in both cases.

An externalId can also be omitted at first and added at a later time. If you deploy an update to your app that assigns an existing user with a new externalId that they didn’t have before, any existing conversation history they have will be preserved and their messages will start being synchronized across all clients where that externalId is being used. This is particularly useful if a user opens Sunshine Conversations and starts a conversation before having logged in to your app or website.

Switching users

If your app allows a shared client to switch between multiple user identities you can call the login API multiple times to switch between different externalIds.

Logging out

Your app may have a logout function which brings users back to a login screen. In this case you would want to revert Sunshine Conversations to a pre-login state. You can do this by calling the logout API.

Calling logout will disconnect your user from any externalId they were previously logged in with and it will remove any conversation history stored on the client. Logging out will not disable Sunshine Conversations. While logged out, the user is free to start a new conversation but they will show up as a different userId on the business end.

Web (JavaScript):

Smooch.logout().then(
    function() {
        // Your code after logout is complete
    },
    function(err) {
        // Something went wrong during logout
    }
);

iOS (Objective-C):

[Smooch logoutWithCompletionHandler:^(NSError * _Nullable error, NSDictionary * _Nullable userInfo) {
    if (error == nil) {
        // Your code after logout is complete
    } else {
        // Something went wrong during logout
    }
}];

iOS (Swift):

Smooch.logout { (error:Error? , userInfo:[AnyHashable : Any]?) in
    if (error == nil) {
        // Your code after logout is complete
    } else {
        // Something went wrong during logout
    }
}

Android (Java):

Smooch.logout(new SmoochCallback() {
    @Override
    public void run(Response response) {
        if (response.getError() == null) {
            // Your code after logout is complete
        } else {
            // Something went wrong during logout
        }
    }
});