Business Messaging Guide v2
Business Messaging
Version 2

Authentication

Copy link

Overview

Copy link

In Sendbird Business messaging, there are two types of authentication:

  • Guest login: A session available without authentication. It's vulnerable security-wise, so it's recommended for testing purposes only. You can disable it in Dashboard Settings - Application - Security - Access token permission.
  • Session token: A session that requires authentication. It needs implementation on the customer server and offers better security.

This guide explains how to use the Session token. The following diagram shows the entire authentication process. Parts that customers don't need to consider about are not shown in the diagram.

  1. The customer client (app) requests login from the customer server, usually using the customer's own login API.
  2. The customer server receives the login request and, if the credentials are valid, requests a token issue from the Sendbird server.
  3. The Sendbird server issues a session token.
  4. The customer server sends the session token to the customer client.
  5. The customer client registers the session token for use in Sendbird authentication calls.
  6. Handle session expiration through the Session Handler.

Everything else is handled automatically. Session expiration is managed in the same way. Now, let's go into detailed explanations with code samples.

Customer Server Implementation

Copy link

1. Login Request or Session Expiration Request

Copy link

The customer client requests login from the customer server, typically using an existing login API.

2. Token Issue Request

Copy link

If the login request is valid, the customer server requests a token issue from the Sendbird server. Use the endpoint `/v3/users/{user_id}/token. For details, refer to this link. The session has an expiration time, with a default of 7 days.

Code Sample

Copy link

This is the very basic example of how to implement the server side code.

from flask import Flask, jsonify
import requests

app = Flask(__name__)

# Sendbird API Information
APPLICATION_ID = "your_application_id"
USER_ID = "user_id"
NOTIFICATIONS_API_TOKEN = "your_notifications_api_token"

def get_sendbird_token(application_id, user_id, api_token):
    url = f"https://api-{application_id}.sendbird.com/v3/users/{user_id}/token"
    headers = {
        "Api-Token": api_token,
        "Content-Type": "application/json"
    }

    response = requests.post(url, headers=headers)

    if response.status_code == 200:
        return response.json()
    else:
        return None

@app.route('/login', methods=['POST'])
def myservice_login():
    token_data = get_sendbird_token(APPLICATION_ID, USER_ID, NOTIFICATIONS_API_TOKEN)

    if token_data:
        return jsonify({
            'user_id': USER_ID,
            'access_token': token_data.get("token"),
            'expires_at': token_data.get("expires_at")
        })
    else:
        return jsonify({
            'error': 'Failed to get token from Sendbird'
        }), 500

if __name__ == '__main__':
    app.run()

Client Implementation

Copy link

1. Authenticating with a Session Token in the SDK

Copy link

The client should pass the session token received from the server to the Sendbird SDK using the appropriate function for each platform and SDK.

Here's how to do it:

  • Android SDK: Use SendbirdChat.authenticate("USER_ID", "SESSION_TOKEN")
  • Android UIKit: Implement the getAccessToken function in the SendbirdUIKitAdapter interface within the SendbirdUIKit.init function to return the session token.
  • iOS SDK: Use $SendbirdChat.authenticate(userId: "USER_ID", authToken)
  • iOS UIKit: Store the session token in SBUGlobals.accessToken.
  • This allows the Sendbird SDK to authenticate the user using the session token, enabling access to chat services.

Below are code samples for each platform.

Android-SDKAndroid-UIKitiOS-SDKiOS-UIKit
myServiceLogin(USER_ID) { response, error ->
    val sendbirdToken = response?.getString("sendbird_token")
    SendbirdChat.authenticate(USER_ID, sendbirdToken) { user: User?, e: SendbirdException? ->
        if (e != null) {
            // Handle error
            return@authenticate
        }

        // Handle user
    }
}

2. Handling Session Expiration with a Session Handler

Copy link

Sessions can expire. When this happens, the client app must communicate with the client server and the Sendbird server to obtain a new session token. This process is managed through a Session Handler, where defined logic handles the necessary actions. Functions within this handler are called at each required moment.

This approach is the same for both UIKit and SDK.

Note: The Session Handler must be registered after the SDK is successfully initialized and before the authenticate call.

AndroidiOS
// WARN: There are some requirements for the session handler. 
// The session delegate needs to be registered after a successful initialization.
// User authentication needs to happen after the session delegate is registered.

class BaseApplication : Application() {
   override fun onCreate() {
       super.onCreate()
      
       // SendbirdChat.init or SendbirUIKit.init
       // TODO: init must be called before setting the session handler.
        SendbirdChat.setSessionHandler(
            object : SessionHandler() {
                override fun onSessionTokenRequired(sessionTokenRequester: SessionTokenRequester) {
                    // A new session token is required in the SDK to refresh the session.
                    // Refresh the session token and pass it onto the SDK through sessionTokenRequester.onSuccess(NEW_TOKEN).
                    // If you do not want to refresh the session, pass on a null value through sessionTokenRequester.onSuccess(null).
                    // If any error occurred while refreshing the token, let the SDK know about it through sessionTokenRequester.onFail().
                    myServiceLogin(USER_ID) { response, error ->
                        if (error != null) {
                             Log.d("SessionHandler", "Session token refresh failed")
                             sessionTokenRequester.onFail()
                        } else {
                             val sendbirdToken = response.getString("access_token")
                             Log.d("SessionHandler", "Session token refreshed")
                             sessionTokenRequester.onSuccess(sendbirdToken)
                        }
                    }
                    Log.d("SessionHandler", "Session token required")
                }

                override fun onSessionClosed() {
                    // The session refresh has been denied from the app.
                    // Client apps should guide the user to a login page to log in again.
                    Log.d("SessionHandler", "Session closed")
                    
                    // TODO (Leo): Check if we need to disconnect the user here (especially for UIKit)
                }

                override fun onSessionRefreshed() {
                    // This is optional and no action is required.
                    // This is called when the session is refreshed.
                    Log.d("SessionHandler", "Session refreshed")
                }

                override fun onSessionError(sendbirdException: SendbirdException) {
                    // This is optional and no action is required.
                    // This is called when an error occurs during the session refresh.
                    Log.d("SessionHandler", "Session error")
                }
            }
        )
   }
}