Authentication
In order to authenticate your users with Copilot, an authentication key should be generated on Copilot.cx backend. Your backend will be responsible for interacting with the Copilot.cx backend in order to generate an authentication key and pass it to your application.
💡 For support in adding authenticated access to your app, please consult your Copilot's Customer Success Manager.
High level diagram
- Your application requires to perform a Copilot.cx command which requires authentication with the Copilot.cx backend.
- The Copilot.cx SDK requires an authentication key from hosting application.
- Your application interacts with your application backend that manages users in order request a Copilot.cx authentication key from the Copilot.cx backend.
- Your application backend requests a Copilot.cx authentication key using the
generate_user_auth_key
request passing the user id. - The Copilot.cx backend generates authentication key and returns it to your application backend as part of the response.
- Your application backend returns the Copilot.cx authentication key to your application.
- Your application passes the Copilot.cx authentication token to the Copilot.cx SDK.
- The Copilot.cx SDK performs the authenticated request to the Copilot.cx backend.
Token provider
The TokenProvider
protocol/interface is the way to implement the interaction above. The TokenProvider.generateAuthKey(String userId)
method will be invoked when there is a requirement from the Copilot.cx SDK to authenticate a call (weather for the first time or not) passing the userId
which was passed as part of the session management component. An object implementing the TokenProvider
protocol/interface should be passed to Copilot.cx SDK as soon as possible.
There's no need to call the
generateAuthKey
command from your own code. The Copilot.cx SDK will invoke that method once authentication is required. Just implement the interface and pass the implementing instance to the Copilot.cx SDK. Do not cache the token internally in your app or your backend, the token is managed by the Copilot.cx SDK and Copilot.cx Cloud. When it expires, a an new call togenerateAuthKey
is made by the Copilot.cx SDK.
Please note : In case the authentication key generation function encounters an error, a proper exception should be thrown:
ConnectivityException
- You application is unable to generate a Copilot.cx authentication key because of a connectivity error (or timeout).GeneralErrorException
- An error which is un-recoverable by the user.
auth_key
Generating the user's (arrows 4 and 5 in diagram)
Your backend, using the service account credentials, should invoke the generate_user_auth_key
API call passing a userId for which the token will be generated. The auth_key
should be passed to the application as part of the TokenProvider
protocol/interface implementation (see below).
Important: This API call must be implemented in your backend and not in your mobile application as it uses the dedicated Copilot.cx cloud service account.
URL
POST https://<BASE_URL>/v2/api/management/your_own/auth/generate_user_auth_key
Request Headers
Authorization: Basic <YOUR_CREDENTIALS_PART>
Content-Type: application/json
Note: The header contains your Copilot.cx management authentication token, generated on the Session Management chapter.
Request Body example
{
"user_id": "eff119c1-47c5-4a77-8fc8-667eb7e354d3"
}
Response example
{
"auth_key": "Y2lPaUpJVXpJMU5eyJhY2Nlc3NfdG9rZW4iOiJleUowZVhBaU9pSktWMVFpTENKaGJH"
}
TokenProvider
protocol/interface
Implementing the //Before starting a session, you should set token provider which implements CopilotTokenProvider
class YourCopilotTokenProvider: CopilotTokenProvider {
func generateUserAuthKey(for userId: String, withClosure closure: @escaping GenerateUserAuthKeyClosure) {
//Generate access token for Copilot.cx using your request manager to interact with your backend.
YourRequestManager().generateAccessToken(userId: userId) { (response) in
switch response {
case .success(let authKey):
closure(.success((authKey)))
case .failure(let error):
// Make sure you invoke the closure with an error when you encounter one. Errors may be `generalError` or `connectivityError`.
closure(.failure(error: .generalError(debugMessage: error.localizedDescription)))
}
}
}
}
public class YourCopilotTokenProvider implements CopilotTokenProvider {
// For example, using your Retrofit object to interact with your backend.
private final YourRetrofit mRetrofit;
public IotcoCopilotTokenProvider(Context context) {
mRetrofit = new YourRetrofit(context);
}
@Override
public String generateUserAuthKey(String userId) throws ConnectivityException, GeneralErrorException {
// Make sure that's the right user id. This is your logged in user.
CopilotTokenResponse copilotTokenResponse = mRetrofit.generateUserAuthKey(userId);
return copilotTokenResponse.getAuthKey();
}
}
class YourCopilotTokenProvider : CopilotTokenProvider {
// For example, using your Retrofit object to interact with your backend.
private var mRetrofit: YourRetrofit? = null
fun IotcoCopilotTokenProvider(context: Context?) {
mRetrofit = YourRetrofit(context)
}
@Throws(ConnectivityException::class, GeneralErrorException::class)
override fun generateUserAuthKey(userId: String): String {
// Make sure that's the right user id. This is your logged in user.
val copilotTokenResponse: CopilotTokenResponse = mRetrofit.generateUserAuthKey(userId)
return copilotTokenResponse.getAuthKey()
}
}
TokenProvider
Setting the Pass a TokenProvider
protocol/interface implementation to Copilot.cx SDK using the setCopilotTokenProvider
method. This invocation should be done as part of the Copilot.cx SDK initialization in your AppDelegate
/Application
classes. Please refer to the following code snippet:
In case a token provider was not provided and an authenticated request is required by the Copilot.cx SDK, an Unauthorized error will be propagated.
let copilotTokenProvider = YourCopilotTokenProvider()
Copilot.instance.manage.yourOwn.auth.setCopilotTokenProvider(copilotTokenProvider)
CopilotTokenProvider tokenProvider = new YourCopilotTokenProvider(this)
Copilot.getInstance().Manage.YourOwn.Auth.setCopilotTokenProvider(tokenProvider);
val tokenProvider: CopilotTokenProvider = YourCopilotTokenProvider(this)
Copilot.getInstance().Manage.YourOwn.Auth.setCopilotTokenProvider(tokenProvider)