Enable Server Side User Authentication
Server-side user authentication in the LikeMinds SDK ensures secure and reliable user verification by handling authentication on the backend. It protects sensitive user data, prevents unauthorized access, and enables seamless session management. This approach enhances security while providing a smooth integration experience for developers.
Prerequisites
For each tech stacks below, LikeMinds Chat SDK should be integrate using the Getting Started Guide.
Steps to Enable Server-Side User Authentication
Step 1: Create an API on your Server to start a User Session with LikeMinds
Create a new API on your backend server that will handle user authentication with LikeMinds. This API should call the LikeMinds Initiate API to create a new user session. The Initiate API will return an accessToken and refreshToken that will be used to authenticate subsequent requests to the LikeMinds SDK.
Step 2: Create a function on Frontend to get tokens
Create a function to get accessToken and refreshToken from your backend using Initiate API.
- Android
 - iOS
 - Flutter
 - ReactJS
 - ReactNative
 
suspend fun getTokens():Pair<String,String>{
  // your implementation to fetch LikeMinds Authentication Tokens
  return Pair(accessToken, refreshToken)
}
func getTokens() -> (String, String)? {
    // your implementation to fetch LikeMinds Authentication Tokens
    return (accessToken, refreshToken)
}
Future<(String, String)> getTokens() async {
...
// implementation
...
return (accessToken, refreshToken);
}
function getTokens() {
  // Your implementation to fetch the LikeMinds Authentication tokens
  // Also save these tokens in the initial state of the application as you will be required to pass these tokens to LMClientOverlayProvider.
}
function getTokens() {
  // Your implementation to fetch the LikeMinds Authentication tokens
  // Also save these tokens in the initial state of the application as you will be required to pass these tokens to LMOverlayProvider.
}
Step 3: Create an instance of LMChatCoreCallbacks
- Android
 - iOS
 - Flutter
 - ReactJS
 - ReactNative
 
While setting up LikeMinds Chat SDK in onCreate() method of the Application class, extend LMChatCoreCallback and pass the instance of the same in LMChatCore.setup()
val application = this // instance of the application
val lmChatTheme = LMChatTheme.COMMUNITY_CHAT // chat theme choosen
val lmChatAppearanceRequest = null // instance of the appearance
val domain = "ENTER YOUR DOMAIN NAME" // domain of the app
val enablePushNotifications = false // enable or disable push notifications
val deviceId = null  // device id of the user
val lmChatCoreCallback = object : LMChatCoreCallback {
    override fun onAccessTokenExpiredAndRefreshed(
        accessToken: String,
        refreshToken: String
    ) {
        Log.d("Example","accessToken: $accessToken, refreshToken: $refreshToken")
    }
    override fun onRefreshTokenExpired(): Pair<String?, String?> {
        return runBlocking {
          getTokens()
        }
    }
}
LMChatCore.setup(
    application = application,
    theme = lmChatTheme,
    lmChatCoreCallback = lmChatCoreCallback,
    lmChatAppearanceRequest = lmChatAppearanceRequest,
    domain = domain,
    enablePushNotifications = enablePushNotifications,
    deviceId = deviceId
)
Implement the LMChatCoreCallback protocol in your class, which has the callbacks to manage tokens.
class ClientSDKCallBack: LMChatCoreCallback {
  func onAccessTokenExpiredAndRefreshed(accessToken: String, refreshToken: String) {
    // Store the updated tokens
  }
  func onRefreshTokenExpired(_ completionHandler: (((accessToken: String, refreshToken: String)?) -> Void)?) {
    // Call inititate api from your backend and return the fetched accessToken and refreshToken
    // completionHandler?((accessToken, refreshToken))
    // In case the call fails, return nil
    // completionHandler?(nil)
  }
}
Set up the LMChatCore package in the main function with the following code and pass LMChatCoreCallback
void main(){
  WidgetsFlutterBinding.ensureInitialized();
  //create callback instance
  final lmChatCallback = LMChatCoreCallback(
      onAccessTokenExpiredAndRefreshed: (accessToken, refreshToken) {
        debugPrint("Access token expired and refreshed");
      },
      onRefreshTokenExpired: () async {
        // get accessToken, refreshToken from your backend
        final (accessToken, refreshToken) = await getTokens();
        // return `LMAuthToken` with `accessToken` and `refreshToken` received from your backend
        return (LMAuthTokenBuilder()
              ..accessToken(accessToken!)
              ..refreshToken(refreshToken!))
            .build();
      },
    )
  // Call setup function before the runApp() function
  await LMChatCore.instance.initialize(
    lmChatCallback: lmChatCallback,
  );
...
runApp(YourApp());
}
Create an instance of LMCoreCallbacks and pass in the necessary callback functions.
const lmCoreCallback = new LMCoreCallbacks(
  onAccessTokenExpiredAndRefreshed(accessToken: string, refreshToken: string) {
    // Handle Access and Refresh token as per your implementation
  },
  async onRefreshTokenExpired() {
    // Get New Tokens and return it in the below format
    return {
      accessToken: "YOUR NEW ACCESS TOKEN",
      refreshToken: "YOUR NEW REFRESH TOKEN",
    };
  }
);
Create an instance of LMCoreCallbacks and pass in the necessary callback functions.
const lmCoreCallback = new LMCoreCallbacks(
  onAccessTokenExpiredAndRefreshed(accessToken: string, refreshToken: string) {
    // Handle Access and Refresh token as per your implementation
  },
  async onRefreshTokenExpired() {
    // Get New Tokens and return it in the below format
    return {
      accessToken: "YOUR NEW ACCESS TOKEN",
      refreshToken: "YOUR NEW REFRESH TOKEN",
    };
  }
);
LMChatCoreCallback has two callbacks:
onAccessTokenExpiredAndRefreshed(): This callback is triggered when the providedaccessTokenexpires and is refreshed internally using therefreshToken.onRefreshTokenExpired()This callback is triggered when the providedrefreshTokenexpires. In this case, you need to provide a newaccessTokenandrefreshTokenfrom your backend server using our initiate API.
Step 4: Send the received token to LikeMinds SDK
Skip this step if you are using AI Chatbot Theme. Navigate to Chatbot Section to know more.
- Android
 - iOS
 - Flutter
 - ReactJS
 - ReactNative
 
Upon receiving the accessToken and refreshToken from your backend server, call LMChatCore.showChat() function with these tokens.
val context = this // instance of context
val accessToken = "RECEIVED ACCESS TOKEN"
val refreshToken = "RECEIVED REFRESH TOKEN"
val successCallback = { response : UserResponse? ->
    //user session initiated successfully, write your logic here
    Unit
} // callback triggered when the initiate user call is successful
val failureCallback = { errorMessage ->
  Log.e("Example", errorMessage)
  Unit
} // callback triggered when the initiate user call fails
LMChatCore.showChat(
    context = context,
    accessToken = accessToken,
    refreshToken = refreshToken,
    success = successCallback,
    error = failureCallback
)
Upon receiving the accessToken and refreshToken from your backend server, call LMChatCore.showChat() function with these tokens and protocol LMChatCoreCallback class.
import LikeMindsChatCore
func application(_ application: UIApplication, willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) {
    // Pass the earlier created Implementation of LMChatCoreCallback
     LikeMindsChatCore.showChat(accessToken: accessToken, refreshToken: refreshToken, handler: ClientSDKCallback(), completionHandler: { })
}
Use the getTokens() function, to fetch the tokens to login without API Key. Upon receiving the accessToken and refreshToken, call LMChatCore.instance.showChatWithoutApiKey() function with these tokens.
// get accessToken, refreshToken from your backend
final (accessToken, refreshToken) = await getTokens();
LMResponse response =
    await LMChatCore.instance.showChatWithoutApiKey(
      accessToken : "YOUR_ACCESS_TOKEN",
      refreshToken : "YOUR_REFRESH_TOKEN",
    );
Open up src/App.js and replace its contents with the following code:
import { useState } from "react";
import {
  LMClientOverlayProvider,
  LMChannel,
  initiateLMClient,
  LMChatTheme,
  LMCoreCallbacks
} from "@likeminds.community/likeminds-chat-reactjs";
function App() {
  const [userDetails, setUserDetails] = useState<{
    accessToken?: string; // Your Access Token
    refreshToken?: string; // Your Refresh Token
  }>({
    accessToken: "ENTER YOUR ACCESS TOKEN",
    refreshToken: "ENTER YOUR REFRESH TOKEN",
  });
  const lmChatClient = initiateLMClient();
  const lmCoreCallback = new LMCoreCallbacks(
    (accessToken: string, refreshToken: string) => {
      // Handle Access and Refresh token as per your implementation
    },
    async () => {
      // Get New Tokens and return it in the below format
      return {
        accessToken: "YOUR NEW ACCESS TOKEN",
        refreshToken: "YOUR NEW REFRESH TOKEN",
      };
    }
  );
  return (
    <LMClientOverlayProvider
      client={lmChatClient}
      userDetails={userDetails}
      lmChatTheme={LMChatTheme.COMMUNITY_CHAT}
      lmChatCoreCallbacks={lmCoreCallback}
    >
      <LMChannel />
    </LMClientOverlayProvider>
  );
}
export default App;
Add the LMOverlayProvider and pass the accessToken and refreshToken returned in Step 2.
import { LMOverlayProvider, Themes } from "@likeminds.community/chat-rn-core";
import { LMCoreCallbacks } from "@likeminds.community/chat-rn-core/ChatSX/setupChat";
import { GestureHandlerRootView } from "react-native-gesture-handler";
const App = () => {
  const [myClient, setMyClient] = useState<any>();
  const accessToken = "<YOUR_INITIAL_ACCESS_TOKEN>";
  const refreshToken = "<USER_INITIAL_REFRESH_TOKEN>";
  const theme = <"SDK_THEME">
  useEffect(() => {
    async function generateClient() {
      // Initiate LMChatClient as described in step 2
      const res: any = initMyClient();
      setMyClient(res);
    }
    generateClient();
  }, []);
  const lmCoreCallback = new LMCoreCallbacks(
    onAccessTokenExpiredAndRefreshed(accessToken: string, refreshToken: string) {
      // Handle Access and Refresh token as per your implementation
    },
    async onRefreshTokenExpired() {
      // Get New Tokens and return it in the below format
      return {
        accessToken: "YOUR NEW ACCESS TOKEN",
        refreshToken: "YOUR NEW REFRESH TOKEN",
      };
    }
  );
  return (
    <GestureHandlerRootView>
      <LMOverlayProvider
        myClient={myClient}
        accessToken={accessToken}
        refreshToken={refreshToken}
        callbackClass={lmCoreCallback}
        theme={theme}
      >
        {/* Follow step 4 of the Getting Started to add navigation logic after user is successfully initiated with LM servers */}
      </LMOverlayProvider>
    </GestureHandlerRootView>
  );
};
export default App;
AI Chatbot Theme
- Android
 - Flutter
 - ReactJS
 - ReactNative
 
While starting the user session, pass the accessToken and refreshToken from getTokens() function as mentioned in Step 2 to the LMChatAIBotButton component, instead of apiKey, userName, uuid.
val accessToken = "RECEIVED ACCESS TOKEN"
val refreshToken = "RECEIVED REFRESH TOKEN"
findViewById<LMChatAIBotButton>(R.id.btn_ai_chatbot).setChatAIButtonProps(
    LMChatAIBotButtonProps.Builder()
        .accessToken(accessToken)
        .refreshToken(refreshToken)
        .build()
)
While adding the LMChatAIBotButton component, pass the accessToken and refreshToken from getTokens() function as mentioned in Step 2 to the LMChatAIBotButton component, instead of apiKey, userName, uuid.
LMChatAIBotButton(
  props: LMChatAIButtonProps(
    accessToken: 'your-access-token',
    refreshToken: 'your-refresh-token',
  ),
);
import { useState } from "react";
import {
  LMChatAIButton,
  initiateLMClient,
} from "@likeminds.community/likeminds-chat-reactjs";
const App = () => {
  const [userDetails, setUserDetails] = useState<{
    accessToken?: string; // Your Access Token
    refreshToken?: string; // Your Refresh Token
  }>({
    accessToken: "ENTER YOUR ACCESS TOKEN",
    refreshToken: "ENTER YOUR REFRESH TOKEN",
  });
  return <LMChatAIButton client={lmChatClient} userDetails={userDetails} />;
};
In the screen where you are rendering the LMChatAIButton component, pass the accessToken and refreshToken from getTokens() function as mentioned in Step 2 to the LMChatAIButton component, instead of apiKey, userName, uuid.
import { LMChatAIButton } from "@likeminds.community/chat-rn-core";
const HomeScreen = () => {
  return (
    <>
      {/* Your existing screen content */}
      <LMChatAIButton
        accessToken="<ACCESS_TOKEN>"
        refreshToken="<REFRESH_TOKEN>"
      />
    </>
  );
};
Conclusion
After completing these steps, your application will be configured with server-side user authentication for the LikeMinds SDK. This setup provides:
- Secure user verification through backend authentication
 - Protected sensitive user data
 - Seamless session management
 - Automatic token refresh handling
 
Make sure to test the authentication flow thoroughly in your development environment before deploying to production.