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 providedaccessToken
expires and is refreshed internally using therefreshToken
.onRefreshTokenExpired()
This callback is triggered when the providedrefreshToken
expires. In this case, you need to provide a newaccessToken
andrefreshToken
from 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.