> ## Documentation Index
> Fetch the complete documentation index at: https://docs.asapp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# User Authentication

As in the Quick Start section, you can connect to chat as an anonymous user by not setting a user, or initializing an `ASAPPUser` with a null customer identifier. However, many chat use cases might require ASAPP to know the identity of the user.

To connect as an identified user, please specify a customer identifier string and a request context provider function. This provider will be called from a background thread, when the SDK makes requests that require customer authentication with your company's servers. The request context provider is a function that returns a map with keys and values agreed upon with ASAPP. Please ask your Implementation Manager if you have questions.

## Example:

```kotlin theme={null}
val requestContextProvider = object : ASAPPRequestContextProvider {
    override fun getASAPPRequestContext(user: ASAPPUser,
                                        refreshContext:Boolean): Map<String, Any>? {
        return mapOf(
            "Auth" to mapOf(
                "Token" to "example-token"
            )
        )
    }
}
ASAPP.instance.user = ASAPPUser("testuser@example.com", requestContextProvider)
```

## Handle Login Buttons

If you connect to chat anonymously, you may be asked to log in when necessary by being shown a message button:

<Frame>
  <img src="https://mintcdn.com/asapp/V0FXHedP7HW51oOw/image/uuid-bbfa4b7a-ca23-7407-c592-a8d5df402b5c.png?fit=max&auto=format&n=V0FXHedP7HW51oOw&q=85&s=f7ba73739835eeba130b45ae70053f49" width="660" height="334" data-path="image/uuid-bbfa4b7a-ca23-7407-c592-a8d5df402b5c.png" />
</Frame>

If you then tap the **Sign In** button, the SDK will use the `ASAPPUserLoginHandler` to call to the application. Due to the asynchronous nature of this flow, your application should use the activity lifecycle to provide a result to the SDK.

How to Implement the Sign In Flow

1. Implement the `ASAPPUserLoginHandler` and start your application's `LoginActivity`, including the given request code.
   ```kotlin theme={null}
   ASAPP.instance.userLoginHandler = object: ASAPPUserLoginHandler {
       override fun loginASAPPUser(requestCode: Int, activity: Activity) {
           val loginIntent = new Intent(activity, LoginActivity::class.java)
           activity.startActivityForResult(loginIntent, requestCode)
       }
   }
   ```
2. If a user successfully signs into your application, update the user instance and then finish your `LoginActivity` with `Activity.RESULT_OK`.
   ```kotlin theme={null}
   ASAPP.instance.user = ASAPPUser(userIdentifier, contextProvider) 
   setResult(Activity.RESULT_OK)
   finish()
   ```
3. In case a user cancels the operation, finish your `LoginActivity` with `Activity.RESULT_CANCELED`.
   ```kotlin theme={null}
   setResult(Activity.RESULT_CANCELED)
   finish()
   ```

After your `LoginActivity` finishes, the SDK will capture the result and resume the chat conversation.

## Token Expiration and Refreshing the Context

If the provided token has expired, the SDK will call the [ASAPPRequestContextProvider](https://docs-sdk.asapp.com/api/chatsdk/android/latest/chatsdk/com.asapp.chatsdk/-a-s-a-p-p-request-context-provider) with an `refreshContext` parameter set to `true` indicating that the context must be refreshed. In that case, please make sure to return a map with fresh credentials that can be used to authenticate the user. In case an API call is required to refresh the credentials, make sure to block the calling thread until the updated context can be returned.
