페이지 이동경로
  • Docs>
  • Kakao Login>
  • Android

Kakao Login

Android

This document describes how to integrate Kakao Login APIs into your service with the Kakao SDK for Android.

To learn about each API in detail, refer to Concepts.

For a Kakao Login button, you can download the resources provided by Kakao or customize buttons according to your service user interface by referring to the Design Guide.

Before you begin

Choose method

Kakao Login enables users to log in through Kakao Talk or their Kakao Account information.

API Method Description
Login with Kakao Talk(Recommended) loginWithKakaoTalk() Log in with the Kakao Account that logged in to the Kakao Talk app.
The user can log in without manually inputting the ID and password.
Login with Kakao Account loginWithKakaoAccount() Log in by entering the ID and password of the Kakao Account on the default browser.
Available on devices where the Kakao Talk app is not installed, or if the service lets the users use multiple Kakao Accounts.

Set Redirect URI

To implement Kakao Login feature, your app must be able to receive the authorization code through redirection. Set an activity in AndroidManifest.xml by referring to the sample below.

<activity android:name="com.kakao.sdk.auth.AuthCodeHandlerActivity"
          android:exported="true">
          
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        
        <!-- Redirect URI: "kakao${YOUR_NATIVE_APP_KEY}://oauth" -->
        <data android:scheme="kakao${YOUR_NATIVE_APP_KEY}" android:host="oauth" />
    </intent-filter>
</activity>

Add an activity and set the name as "com.kakao.sdk.auth.AuthCodeHandlerActivity". If the app targets Android 12 or higher, set exported to "true".

Specify redirect_uri by adding host and scheme data in <intent-filter>. scheme must be in kakao${NATIVE_APP_KEY} format. For example, if the native app key is "123456789", input "kakao123456789".

When the authorization server sends an authorization code to the specified redirect_uri, the Android SDK receives the authorization code and requests an access token. Refer to Concepts to see the login process.

Set Custom URL scheme

To use Select shipping address API, set the Activity in the AndroidManifest.xml.

<application>
    <activity
        android:name="com.kakao.sdk.auth.AppsHandlerActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.VIEW" />

            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />

            <!-- Setting for the shipping address picker -->
            <data android:scheme="kakao${YOUR_NATIVE_APP_KEY}" />
            <data android:host="address" />
        </intent-filter>
    </activity>
</application>

Login

Basic information
Reference App setting
[SDK] isKakaoTalkLoginAvailable()
[SDK, RxSDK] loginWithKakaoTalk()
[SDK, RxSDK] loginWithKakaoAccount()
[SDK, RxSDK] loginWithNewScopes()
[SDK] OAuthToken
Install
Initialize
Set Redirect URI
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Manage consent items
Advanced: Activate OpenID Connect(Optional)
Set Simple Signup(for Kakao Sync)
Required Required:
Required consent item

Login with Kakao Talk

Request

Call loginWithKakaoTalk() method that runs Kakao Talk and prompts the Consent screen that asks consent.

Response

When a user consents, Kakao identifies the user with the user's Kakao Account information linked to Kakao Talk, and then issues tokens. The Android SDK provides the issued tokens through the OAuthToken object.

Sample

Kotlin
RxKotlin
// Login with Kakao Talk
UserApiClient.instance.loginWithKakaoTalk(context) { token, error ->
    if (error != null) {
        Log.e(TAG, "Login failed.", error)
    }
    else if (token != null) {
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }
}
var disposables = CompositeDisposable()

// Login with Kakao Talk
UserApiClient.rx.loginWithKakaoTalk(context)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ token ->
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }, { error ->
        Log.e(TAG, "Login failed.", error)
    })
    .addTo(disposables)

Login with Kakao Account

Request

Call loginWithKakaoAccount() method that opens a default web browser and prompts the Consent screen that asks consent.

Response

When a user consents, Kakao identifies the user through the user's Kakao Account cookie stored on the default web browser and then issues tokens through the OAuthToken class.

Sample

Kotlin
RxKotlin
//  Login with Kakao Account
UserApiClient.instance.loginWithKakaoAccount(context) { token, error ->
    if (error != null) {
        Log.e(TAG, "Login failed.", error)
    }
    else if (token != null) {
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }
}
var disposables = CompositeDisposable()

//  Login with Kakao Account
UserApiClient.rx.loginWithKakaoAccount(context)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ token ->
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }, { error ->
        Log.e(TAG, "Login failed.", error)
    })
    .addTo(disposables)

Kakao Login Sample

This is a sample that includes basic exception handling required when logging in to Kakao. Refer to the reference and Troubleshooting.

Kotlin
RxKotlin
// Login common callback 
val callback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
    if (error != null) {
        Log.e(TAG, "Login failed.", error)
    } else if (token != null) {
        Log.i(TAG, "Login succeeded. ${token.accessToken}")
    }
}

// If Kakao Talk is installed on user's device, proceed to log in with Kakao Talk. Otherwise, implement to log in with Kakao Account.
if (UserApiClient.instance.isKakaoTalkLoginAvailable(context)) {
    UserApiClient.instance.loginWithKakaoTalk(context) { token, error ->
        if (error != null) {
            Log.e(TAG, "Login failed.", error)

            // After installing Kakao Talk, if a user does not complete app permission and cancels Login with Kakao Talk, skip to log in with Kakao Account, considering that the user does not want to log in. 
            // You could implement other actions such as going back to the previous page.
            if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
                return@loginWithKakaoTalk
            }

            // If a user is not logged into Kakao Talk after installing Kakao Talk and allowing app permission, make the user log in with Kakao Account.
            UserApiClient.instance.loginWithKakaoAccount(context, callback = callback)
        } else if (token != null) {
            Log.i(TAG, "Login succeeded. ${token.accessToken}")
        }
    }
} else {
    UserApiClient.instance.loginWithKakaoAccount(context, callback = callback)
}
var disposables = CompositeDisposable()

// If Kakao Talk has been installed, log in with Kakao Talk. Otherwise, log in with Kakao Account.
if (UserApiClient.instance.isKakaoTalkLoginAvailable(context)) {
    UserApiClient.rx.loginWithKakaoTalk(context)
        .observeOn(AndroidSchedulers.mainThread())
        .onErrorResumeNext { error ->
            // After installing Kakao Talk, if a user does not complete app permission and cancels Login with Kakao Talk, skip to log in with Kakao Account, considering that the user does not want to log in.
            // You could implement other actions such as going back to the previous page.
            if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
                Single.error(error)
            } else {
                // If a user is not logged into Kakao Talk after installing Kakao Talk and allowing app permission, make the user log in with Kakao Account.
                UserApiClient.rx.loginWithKakaoAccount(context)
            }
        }.observeOn(AndroidSchedulers.mainThread())
        .subscribe({ token ->
            Log.i(TAG, "Login succeeded. ${token.accessToken}")
        }, { error ->
            Log.e(TAG, "Login failed.", error)
        }).addTo(disposables)
} else {
    UserApiClient.rx.loginWithKakaoAccount(context)
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe({ token ->
            Log.i(TAG, "Login succeeded. ${token.accessToken}")
        }, { error ->
            Log.e(TAG, "Login failed.", error)
        }).addTo(disposables)
}

Additional Feature

Additional features for Kakao Login are below.

Request additional consent

To request additional consent, call loginWithNewScopes(). Pass the scopes of user information you want to request additional consent as a list of strings.

Here is an example of checking which scopes are required to get consent with the me() method and requesting additional consent by passing scopes when calling loginWithNewScopes().

Kotlin
RxKotlin
// Retrieving user information (additional consent)

// You can request additional consent when the user attempts to use a service 
// that requires specific user information and then obtain the user information as follows. 

//  * CAUTION: Consider the case that users refuse to consent to 'Optional consent' item 
// to prevent a problem with the use of the service. 

// Example that checks available scopes and requests consent to all available scopes.
UserApiClient.instance.me { user, error ->
    if (error != null) {
        Log.e(TAG, "Failed to retrieve user information.", error)
    }
    else if (user != null) {
        var scopes = mutableListOf<String>()

        if (user.kakaoAccount?.emailNeedsAgreement == true) { scopes.add("account_email") }
        if (user.kakaoAccount?.birthdayNeedsAgreement == true) { scopes.add("birthday") }
        if (user.kakaoAccount?.birthyearNeedsAgreement == true) { scopes.add("birthyear") }
        if (user.kakaoAccount?.genderNeedsAgreement == true) { scopes.add("gender") }
        if (user.kakaoAccount?.phoneNumberNeedsAgreement == true) { scopes.add("phone_number") }
        if (user.kakaoAccount?.profileNeedsAgreement == true) { scopes.add("profile") }
        if (user.kakaoAccount?.ageRangeNeedsAgreement == true) { scopes.add("age_range") }

        if (scopes.count() > 0) {
            Log.d(TAG, "Need to obtain consent from user.")

            // If OpenID Connect (OIDC) is enabled,
            // - When "openid" is added to `scopes`, OIDC is applied.
            // - When "openid" is not added to `scopes`, OAuth 2.0 is applied. 
                                                
            // To use OIDC, add "openid" to `scopes`.
            // scopes.add("openid")

            UserApiClient.instance.loginWithNewScopes(context, scopes) { token, error ->
                if (error != null) {
                    Log.e(TAG, "Failed to obtain additional consent.", error)
                } else {
                    Log.d(TAG, "allowed scopes: ${token!!.scopes}")

                    // Re-request user information
                    UserApiClient.instance.me { user, error ->
                        if (error != null) {
                            Log.e(TAG, "Failed to retrieve user information.", error)
                        }
                        else if (user != null) {
                            Log.i(TAG, "Succeeded in retrieving user information.")
                        }
                    }
                }
            }
        }
    }
}
var disposables = CompositeDisposable()

// Retrieving user information (additional consent)

// You can request additional consent when the user attempts to use a service 
// that requires specific user information and then obtain the user information as follows. 


//  * CAUTION: Consider the case that users refuse to consent to 'Optional consent' item 
// to prevent a problem with the use of the service. 

// Example that checks available scopes and requests consent to all available scopes.
UserApiClient.rx.me()
    .flatMap { user ->

        var scopes = mutableListOf<String>()

        if (user.kakaoAccount?.emailNeedsAgreement == true) { scopes.add("account_email") }
        if (user.kakaoAccount?.birthdayNeedsAgreement == true) { scopes.add("birthday") }
        if (user.kakaoAccount?.birthyearNeedsAgreement == true) { scopes.add("birthyear") }
        if (user.kakaoAccount?.genderNeedsAgreement == true) { scopes.add("gender") }
        if (user.kakaoAccount?.phoneNumberNeedsAgreement == true) { scopes.add("phone_number") }
        if (user.kakaoAccount?.profileNeedsAgreement == true) { scopes.add("profile") }
        if (user.kakaoAccount?.ageRangeNeedsAgreement == true) { scopes.add("age_range") }

        if (scopes.count() > 0) {
            Log.d(TAG, "Need to obtain consent from user.")

            // If OpenID Connect (OIDC) is enabled,
            // - When "openid" is added to `scopes`, OIDC is applied.
            // - When "openid" is not added to `scopes`, OAuth 2.0 is applied. 
                                                
            // To use OIDC, add "openid" to `scopes`.
            // scopes.add("openid")

            // InsufficientScope  error occurs
            Single.error(ApiError.fromScopes(scopes))
        }
        else {
            Single.just(user)
        }
    }
    .retryWhen(
        // Request additional consent for InsufficientScope.
        RxAuthOperations.instance.incrementalAuthorizationRequired(context)
    )
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ user ->
        Log.i(TAG, "Succeeded in retrieving user information.")
    }, { error ->
        Log.e(TAG, "Failed to retrieve user information.", error)
    })
    .addTo(disposables)

Get consent to desired service terms

Note

This API is only allowed for the service that adopted Kakao Sync.

To request consent to specific service terms from a user, pass the list of service term tags through serviceTerms as an argument. Include at least one required service term's tag to prompt the consent screen.

Kotlin
RxKotlin
// Get consent to desired service terms

// Designate tags for the service terms that you want to get consent
// among the service terms registered in [My Application] > [Kakao Login] > [Simple Signup] in Kakao Developers. 
val serviceTerms = listOf("service")

// Request login with Kakao Talk using the serviceTerms parameter (same for Login with Kakao Account)
UserApiClient.instance.loginWithKakaoTalk(
    context = context,
    serviceTerms = serviceTerms
) { token, error ->
    if (error != null) {
        Log.e(TAG, "Login fail", error)
    }
    else if (token != null) {
        Log.i(TAG, "Login success ${token.accessToken}")
    }
}
var disposables = CompositeDisposable()

// Get consent to desired service terms

// Designate tags for the service terms that you want to get consent
// among the service terms registered in [My Application] > [Kakao Login] > [Simple Signup] in Kakao Developers.
val serviceTerms = listOf("service")

// Request login with Kakao Talk using the serviceTerms parameter (same for Login with Kakao Account)
UserApiClient.rx.loginWithKakaoTalk(
    context = context,
    serviceTerms = serviceTerms
)
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ token ->
        Log.i(TAG, "Login success ${token.accessToken}")
    }, { error ->
        Log.e(TAG, "Login fail", error)
    })
    .addTo(disposables)

Request reauthentication

You can request reauthentication regardless of a user's login status to enhance security. Set prompts to Prompt.LOGIN, and pass it along with context. Then, the login screen is prompted even though a user has already been logged in on the same web browser on the device.

Kotlin
RxKotlin
UserApiClient.instance.loginWithKakaoAccount(context, prompts = listOf(Prompt.LOGIN)) { token, error ->
    if (error != null) {
        Log.e(TAG, "Login failed.", error)
    }
    else if (token != null) {
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }
}
var disposables = CompositeDisposable()

UserApiClient.rx.loginWithKakaoAccount(context, prompts = listOf(Prompt.LOGIN))
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ token ->
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }, { error ->
        Log.e(TAG, "Login failed.", error)
    })
    .addTo(disposables)

Log in after signing up for Kakao Account

You can request to prompt the Kakao Account sign-up page before Kakao Login. Set prompts to Prompt.CREATE, and pass it along with context. The Kakao Login consent screen will be present after signing up for Kakao Account.

Kotlin
RxKotlin
UserApiClient.instance.loginWithKakaoAccount(context, prompts = listOf(Prompt.CREATE)) { token, error ->
    if (error != null) {
        Log.e(TAG, "Login failed.", error)
    }
    else if (token != null) {
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }
}
var disposables = CompositeDisposable()

UserApiClient.rx.loginWithKakaoAccount(context, prompts = listOf(Prompt.CREATE))
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ token ->
        Log.i(TAG, "Login succeeded.${token.accessToken}")
    }, { error ->
        Log.e(TAG, "Login failed.", error)
    })
    .addTo(disposables)

Login hint

To fill in the ID automatically, use the loginHint parameter. The value of the loginHint parameter will be entered in the Kakao Account login page.

Kotlin
RxKotlin
// Login with Kakao Account
UserApiClient.instance.loginWithKakaoAccount(context, loginHint = "${HINT}") { token, error ->
    if (error != null) {
        Log.e(TAG, "Login succeeded.", error)
    }
    else if (token != null) {
        Log.i(TAG, "Login failed. ${token.accessToken}")
    }
}
var disposables = CompositeDisposable()

// Login with Kakao Account
UserApiClient.rx.loginWithKakaoAccount(context, loginHint = "${HINT}")
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ token ->
        Log.i(TAG, "Login succeeded. ${token.accessToken}")
    }, { error ->
        Log.e(TAG, "Login failed.", error)
    })
    .addTo(disposables)

Check token presence

Basic information
Reference App setting
[SDK] hasToken() Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Required -

Checks if a user has obtained an access token through Kakao Login.

Request

Call hasToken().

Response

This API returns the presence of an access token or refresh token as a boolean type. However, note that the return value true does not guarantee that the user is in a logged-in state.

If the value false is returned, it means that tokens do not exist. In this case, implement a process for a user to log in to issue tokens. On the other hand, if the return value is true, you can validate the access token that the user has through the accessTokenInfo() method, and then proceed as follows depending on the request result:

  • If the request is successful, the access token information is returned,
    • Access token is valid, which means the user does not need to log in.
    • You can call the Kakao APIs with the access token.
  • If an error occurs,
    • Access and refresh tokens are invalid, which means the user needs to log in.
    • You need to handle errors by referring to the reference.

Sample

Kotlin
RxKotlin
if (AuthApiClient.instance.hasToken()) {
    UserApiClient.instance.accessTokenInfo { _, error ->
        if (error != null) {
            if (error is KakaoSdkError && error.isInvalidTokenError() == true) {
                //Login is required.
            }
            else {
                //Handle other errors.
            }
        }
        else {
            //Succeeded in validating token (Token is refreshed if needed).
        }
    }
}
else {
    //Login is required.
}
var disposables = CompositeDisposable()

if (AuthApiClient.instance.hasToken()) {
    UserApiClient.rx.accessTokenInfo()
            .subscribe({ tokenInfo ->
                //Succeeded in validating token (Token is refreshed if needed).

            }, { error ->
                if (error != null) {
                    if (error is KakaoSdkError && error.isInvalidTokenError() == true) {
                        //Login is required.
                    }
                    else {
                        //Handle other errors.
                    }
                }
                else {
                    //Succeeded in validating token (Token is refreshed if needed).
                }

            })
            .addTo(disposables)
}
else {
    //Login is required.
}

Logout

Basic information
Reference App setting
[SDK, RxSDK] logout() Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Required -

Makes the issued access token and the refresh token expire.

Request

Call logout().

Response

The Logout API deletes the access and refresh token issued through the login process to have a user log out.

Regardless of the result of the logout request, the Android SDK deletes the access and refresh tokens and has the login session end.

Sample

Kotlin
RxKotlin
// Logout
UserApiClient.instance.logout { error ->
    if (error != null) {
        Log.e(TAG, "Logout fail. Tokens are deleted from SDK", error)
    }
    else {
        Log.i(TAG, "Logout success. Tokens are deleted from SDK")
    }
}
var disposables = CompositeDisposable()

// Logout
UserApiClient.rx.logout()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({
        Log.i(TAG, "Logout success. Tokens are deleted from SDK.")
    }, { error ->
        Log.e(TAG, "Logout fail. Tokens are deleted from SDK.", error)
    }).addTo(disposables)

Unlink

Basic information
Reference App setting
[SDK, RxSDK] unlink() Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Required -

Unlinks the user and the service app.

Request

Call unlink().

Response

If the request is successful, the Android SDK deletes the access and refresh tokens. As the issued tokens are deleted, the session between an app and a user is disconnected, and the user is logged out and unlinked from your app.

Sample

Kotlin
RxKotlin
// Unlink
UserApiClient.instance.unlink { error ->
    if (error != null) {
        Log.e(TAG, "Unlink fail", error)
    }
    else {
        Log.i(TAG, "Unlink success. Tokens are deleted from SDK.")
    }
}
var disposables = CompositeDisposable()

// Unlink
UserApiClient.rx.unlink()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({
        Log.i(TAG, "Unlink success. Tokens are deleted from SDK.")
    }, { error ->
        Log.e(TAG, "Unlink fail", error)
    }).addTo(disposables)

Retrieve token information

Basic information
Reference App setting
[SDK, RxSDK] accessTokenInfo()
[SDK] AccessTokenInfo
Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Required -

Retrieves the validity period of the access and refresh tokens in seconds, app ID and service user ID.

Request

Call accessTokenInfo().

Response

Refer to REST API for detailed response information.

Sample

Kotlin
RxKotlin
// Retrieving token information
UserApiClient.instance.accessTokenInfo { tokenInfo, error ->
    if (error != null) {
        Log.e(TAG, "Failed to retrieve token information.", error)
    }
    else if (tokenInfo != null) {
        Log.i(TAG, "Retrieving token information success" +
                "\nService user ID: ${tokenInfo.id}" +
                "\nValidity period: ${tokenInfo.expiresIn} seconds")
    }
}
var disposables = CompositeDisposable()

// Retrieving token information
UserApiClient.rx.accessTokenInfo()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ tokenInfo ->
        Log.i(TAG, "Retrieving token information success" +
                "\nService user ID: ${tokenInfo.id}" +
                "\nValidity period: ${tokenInfo.expiresIn} seconds")
    }, { error ->
        Log.e(TAG, "Failed to retrieve token information.", error)
    })
    .addTo(disposables)

Retrieve user information

Basic information
Reference App setting
[SDK, RxSDK] me()
[SDK] User
Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Manage consent items
Required Required:
All consent items to request user information

Retrieves Kakao Account information of a user who is logged into Kakao.

Request

Call me().

Response

The user information in response to this request is passed through the User class defined.

Refer to REST API for detailed response information.

Sample

Here is an example of retrieving user information — Service user ID, email, nickname and profile thumbnail image URI.

Kotlin
RxKotlin
// Retrieving user information (Default) 
UserApiClient.instance.me { user, error ->
    if (error != null) {
        Log.e(TAG, "Retrieving user information fails", error)
    }
    else if (user != null) {
        Log.i(TAG, "Retrieving user information succeeds" +
                "\nService user ID: ${user.id}" +
                "\nEmail: ${user.kakaoAccount?.email}" +
                "\nNickname: ${user.kakaoAccount?.profile?.nickname}" +
                "\nProfile Thumbnail Image URI: ${user.kakaoAccount?.profile?.thumbnailImageUrl}")
    }
}
var disposables = CompositeDisposable()

// Retrieving user information (Default) 
UserApiClient.rx.me()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ user ->
        Log.i(TAG, "Retrieving user information succeeds" +
                "\nService user ID: ${user.id}" +
                "\nEmail: ${user.kakaoAccount?.email}" +
                "\nNickname: ${user.kakaoAccount?.profile?.nickname}" +
                "\nProfile Thumbnail Image URI: ${user.kakaoAccount?.profile?.thumbnailImageUrl}")
    }, { error ->
        Log.e(TAG, "Retrieving user information fails", error)
    })
    .addTo(disposables)

Store user information

Basic information
Reference App setting
[SDK, RxSDK] updateProfile() Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Manage user properties
Required -

Stores or updates additional user information on the Kakao platform to use in a service, which is called 'User properties'. You can store or update additional user information into the user property keys that you designated in [My Application] > [Kakao Login] > [User Properties].

Request

Call updateProfile(). You must pass the custom property keys and values that you want to upadate through properties in a key-value pair using mapOf. For example, if you want to update a user's clothing size, set properties to mapOf("clothing_size" to "small").

Response

The response includes the service user ID.

Sample

Kotlin
RxKotlin
// Storing user information

// Properties to be updated
val properties = mapOf("${CUSTOM_PROPERTY_KEY}" to "${CUSTOM_PROPERTY_VALUE}")

UserApiClient.instance.updateProfile(properties) { error ->
    if (error != null) {
        Log.e(TAG, "Storing user information fails", error)
    }
    else {
        Log.i(TAG, "Storing user information succeeds")
    }
}
var disposables = CompositeDisposable()

// Storing user information

// Properties to be updated
val properties = mapOf("${CUSTOM_PROPERTY_KEY}" to "${CUSTOM_PROPERTY_VALUE}")

UserApiClient.rx.updateProfile(properties)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({
        Log.i(TAG, "Storing user information succeeds")
    }, { error ->
        Log.e(TAG, "Storing user information fails", error)
    })

Shipping address

Basic information
Reference App setting
[SDK, RxSDK] selectShippingAddresses()
[SDK, RxSDK] shippingAddresses()
[SDK] UserShippingAddresses
Install
Initialize
Set Custom URL scheme
Permission Prerequisite Kakao Login User consent
Required Register platforms
Activate Kakao Login
Manage consent items
Required Required:
Shipping information

Select shipping address

Prompts the shipping address picker to allow users to select a shipping address and returns the selected shipping address ID.

Request

Call selectShippingAddresses().

Response

This API returns an addressId for the selected shipping address. Request Retrieve shipping address with the addressId to get the detailed shipping address.

Refer to Troubleshooting for the error cause.

Sample

Kotlin
RxKotlin
UserApiClient.instance.selectShippingAddresses(context) { addressId, error ->
    if (error != null) {
        Log.i(TAG, "Failed to select a shipping address $error")
        return@selectShippingAddresses
    }

    UserApiClient.instance.shippingAddresses(addressId!!) { userShippingAddresses, err ->
        if (err != null) {
            Log.i(TAG, "Failed to retrieve the shipping address $err")
        } else if (userShippingAddresses != null) {
            Log.i(
                TAG, "Success" +
                        "\nService user ID: ${userShippingAddresses.userId}" +
                        "\nShipping address: \n${
                            userShippingAddresses.shippingAddresses?.joinToString(
                                "\n"
                            )
                        }"
            )
        }
    }
}
val disposables = CompositeDisposable()

UserApiClient.rx.selectShippingAddresses(context)
    .flatMap {
        UserApiClient.rx.shippingAddresses()
    }
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ userShippingAddresses ->
        if (userShippingAddresses.shippingAddresses != null) {
            Log.i(
                TAG, "Success" +
                        "\nService user ID: ${userShippingAddresses.userId}" +
                        "\nShipping address: \n${
                            userShippingAddresses.shippingAddresses?.joinToString(
                                "\n"
                            )
                        }"
            )
        }
    }, { error ->
        Log.e(TAG, "Failed to retrieve the shipping address", error)
    })
.addTo(disposables)

Retrieve shipping address

This API enables you to retrieve shipping addresses saved in user's Kakao Account.

Request

Call shippingAddresses().

Specify the address ID to the address_id parameter.

Response

shippingAddresses() returns the UserShippingAddresses object.

If not using Select shipping address API, the response may not include the shipping address when the user did not consent to the [Shipping information]. Refer to No shipping address in the response.

Refer to Troubleshooting for the error cause.

Sample

Kotlin
RxKotlin
// Retrieve shipping address with requesting additional consent
UserApiClient.instance.shippingAddresses { userShippingAddresses, error ->
    if (error != null) {
        Log.e(TAG, "Failed to retrieve shipping address", error)
    }
    else if (userShippingAddresses != null) {
        if (userShippingAddresses.shippingAddresses != null) {
            Log.i(TAG, "Succeeded in retrieving shipping addresses" +
                    "\nService user ID: ${userShippingAddresses.userId}" +
                    "\nShipping addresses: \n${userShippingAddresses.shippingAddresses?.joinToString("\n")}")
        }
        else if (userShippingAddresses.needsAgreement == false) {
            Log.e(TAG, "User account does not have a shipping address. If required, select 'Provision after collecting information' option in [My Application] > [Kakao Login] > [Consent items].")
        }
        else if (userShippingAddresses.needsAgreement == true) {
            Log.d(TAG, "You must obtain consent to providing shipping address from a user.")

            val scopes = listOf("shipping_address")

            // Request consent to providing shipping address 
            UserApiClient.instance.loginWithNewScopes(context, scopes) { token, error ->
                if (error != null) {
                    Log.e(TAG, "Failed to get consent to providing shipping address", error)
                }
                else if (token != null) {
                    Log.d(TAG, "allowed scopes: ${token.scopes}")

                    // Retry the request retrieving shipping address
                    UserApiClient.instance.shippingAddresses { userShippingAddresses, error ->
                        if (error != null) {
                            Log.e(TAG, "Failed to retrieve shipping address", error)
                        }
                        else if (userShippingAddresses != null) {
                            Log.i(TAG, "Succeeded in retrieving shipping addresses" +
                                    "\nService user ID: ${userShippingAddresses.userId}" +
                                    "\nShipping addresses: \n${userShippingAddresses.shippingAddresses?.joinToString("\n")}")
                        }
                    }
                }
            }
        }
    }
}
var disposables = CompositeDisposable()

// Retrieve shipping address with requesting additional consent
UserApiClient.rx.shippingAddresses()
    .flatMap { userShippingAddresses ->
        if (userShippingAddresses.needsAgreement == true) {
            Log.d(TAG, "You must obtain consent to providing shipping address from a user.")

            // If InsufficientScope error occurs
            Single.error(ApiError.fromScopes(listOf("shipping_address")))
        }
        else {
            Single.just(userShippingAddresses)
        }
    }
    .retryWhen(
        //  Retry the request the Retrieving shipping address API after requesting additional consent to resolve the InsufficientScope error.
        RxAuthOperations.instance.incrementalAuthorizationRequired(context)
    )
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ userShippingAddresses ->
        if (userShippingAddresses.shippingAddresses != null) {
            Log.i(TAG, "Succeeded in retrieving shipping addresses" +
                    "\nService user ID: ${userShippingAddresses.userId}" +
                    "\nShipping addresses: \n${userShippingAddresses.shippingAddresses?.joinToString("\n")}")
        } else {
            Log.e(TAG, "User account does not have a shipping address. If required, select 'Provision after collecting information' option in [My Application] > [Kakao Login] > [Consent items].")
        }
    }, { error ->
        Log.e(TAG, "Failed to retrieve shipping address", error)
    })
    .addTo(disposables)

Retrieve consent details

Basic information
Reference App setting
[SDK, RxSDK] scopes()
[SDK] ScopeInfo
Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Manage consent items
Required -

Retrieves the detailed information of the scopes (consent items) that a user has agreed to. You can check all scopes set in [My Application] > [Kakao Login] > [Consent Items] and the details of the scopes. If a user has consented to the scope before, the scope is included in the response even though your app is currently not using the scope.

Request

Call scopes().

Response

The response includes consent details of each scope in ScopeInfo object.

Refer to REST API for detailed response information.

Sample

Kotlin
RxKotlin
UserApiClient.instance.scopes { scopeInfo, error->
    if (error != null) {
        Log.e(TAG, "Failed to retrieve consent details.", error)
    }else if (scopeInfo != null) {
        Log.i(TAG, "Succeeded in retrieving consent details succeeds.\n Scopes being used or agreed: $scopeInfo")
    }
}
var disposables = CompositeDisposable()

UserApiClient.rx.scopes()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ scopeInfo: ScopeInfo?->
        Log.i(TAG, "Succeeded in retrieving consent details succeeds.\n Scopes being used or agreed: $scopeInfo")
    }, { error: Throwable? ->
        Log.e(TAG, "Failed to retrieve consent details.", error)
    }).addTo(disposables)

Additional feature

Check specific scopes

You can also retrieve the information of specific scopes by passing scope IDs. In this case, the response includes only the detailed information of the specified scopes if the request is successful.

Kotlin
RxKotlin
// List of the scope IDs that you want to retrieve
val scopes = mutableListOf("account_email", "friends")

UserApiClient.instance.scopes(scopes) { scopeInfo, error->
    if (error != null) {
        Log.e(TAG, "Failed to retrieve consent details.", error)
    }else if (scopeInfo != null) {
        Log.i(TAG, "Succeeded in retrieving consent details succeeds.\n Scopes being used or agreed: $scopeInfo")
    }
}
var disposables = CompositeDisposable()

// List of the scope IDs that you want to retrieve
val scopes = mutableListOf("account_email", "friends")

UserApiClient.rx.scopes(scopes)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ scopeInfo: ScopeInfo?->
        Log.i(TAG, "Succeeded in retrieving consent details succeeds.\n Scopes being used or agreed: $scopeInfo")
    }, { error: Throwable? ->
        Log.e(TAG, "Failed to retrieve consent details.", error)
    }).addTo(disposables)

Revoke consent

Basic information
Reference App setting
[SDK, RxSDK] revokeScopes()
[SDK] ScopeInfo
Install
Initialize
Permission Prerequisite Kakao Login User consent
- Register platforms
Activate Kakao Login
Manage consent items
Required -

Revokes the scope that a user has agreed to.

Request

Call revokeScopes().

Response

If the request is successful, revokeScopes() returns the ScopeInfo object that includes the changed details of each scope and whether a user has agreed to the scope.

Sample

Kotlin
RxKotlin
// List of the scope IDs that you want to revoke
val scopes = mutableListOf("account_email", "legal_birth_date", "friends")

UserApiClient.instance.revokeScopes(scopes) { scopeInfo, error->
    if (error != null) {
        Log.e(TAG, "Failed to revoke consent.", error)
    }else if (scopeInfo != null) {
        Log.i(TAG, "Succeeded in revoking consent.\n Scopes being used or agreed: $scopeInfo")
    }
}
var disposables = CompositeDisposable()

// List of the scope IDs that you want to revoke
val scopes = mutableListOf("account_email", "legal_birth_date", "friends")

UserApiClient.rx.revokeScopes(scopes)
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ scopeInfo: ScopeInfo?->
        Log.i(TAG, "Succeeded in revoking consent.\n Scopes being used or agreed: $scopeInfo")
    }, {error: Throwable? ->
        Log.e(TAG, "Failed to revoke consent.", error)
    }).addTo(disposables)

Service terms

Basic information
Reference App setting
[SDK, RxSDK] serviceTerms()
[SDK, RxSDK] revokeServiceTerms()
[SDK] ServiceTerms
[SDK] UserServiceTerms
[SDK] RevokedServiceTerms
[SDK] UserRevokedServiceTerms
Install
Initialize
Permission Prerequisite Kakao Login User consent
Required: Kakao Sync Register platforms
Activate Kakao Login
Manage consent items
Set Simple Signup
Required -
Note

This API is only allowed for the service that adopted Kakao Sync.

Retrieve consent details for service terms

Checks the service terms that a user has consented to.

Request

Call serviceTerms().

Response

serviceTerms() returns the UserServiceTerms object.

Refer to REST API for detailed response information.

Sample

Kotlin
RxKotlin
// Retrieve consent details for service terms
UserApiClient.instance.serviceTerms { userServiceTerms, error ->
    if (error != null) {
        Log.e(TAG, "Failed to retrieve consent details for service terms", error)
    } else if (userServiceTerms != null) {
        Log.i(
            TAG, "Success in retrieving consent details for service terms" +
                    "\nService user ID: ${userServiceTerms.id}" +
                    "\nService terms: \n${userServiceTerms.serviceTerms?.joinToString("\n")}"
        )
    }
}
// Retrieve consent details for service terms
UserApiClient.rx.serviceTerms()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ userServiceTerms ->
        Log.i(
            TAG, "Success in retrieving consent details for service terms" +
                    "\nService user ID: ${userServiceTerms.id}" +
                    "\nService terms: \n${userServiceTerms.serviceTerms?.joinToString("\n")}"
        )
    }, { error ->
        Log.e(TAG, "Failed to retrieve consent details for service terms", error)
    }).addTo(disposables)

Revoke consent for service terms

Revoke a service terms that a specific user has agreed to. Only service terms with a revocable value of true in the Retrieve consent details for service terms response can be revoked.

Request

Call revokeServiceTerms(). Specify the tags of the service terms you want to revoke consent for in tags.

Response

revokeServiceTerms() returns the UserRevokedServiceTerms object.

Refer to REST API for detailed response information.

Sample

Kotlin
RxKotlin
// Revoke consent for service terms
UserApiClient.instance.revokeServiceTerms(tags = listOf("test_tag1", "test_tag2")) { userRevokedServiceTerms, error ->
    if (error != null) {
        Log.e(TAG, "Failed to revoke consent for service terms", error)
    } else if (userRevokedServiceTerms != null) {
        Log.i(
            TAG, "Success in Revoke consent for service terms" +
                    "\Service user ID: ${userRevokedServiceTerms.id}" +
                    "\nRevoked service terms: \n${userRevokedServiceTerms.revokedServiceTerms?.joinToString("\n")}"
        )
    }
}
// Revoke consent for service terms
UserApiClient.rx.revokeServiceTerms(listOf("test_tag1", "test_tag2"))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ revokedServiceTerms ->
        Log.i(
            TAG, "Success in Revoke consent for service terms" +
                    "\nService user ID: ${revokedServiceTerms.id}" +
                    "\nRevoked service terms: \n${revokedServiceTerms.revokedServiceTerms?.joinToString("\n")}"
        )
    }, { error ->
        Log.e(TAG, "Failed to revoke consent for service terms", error)
    }).addTo(disposables)

Advanced: Manual signup

Basic information
Reference App setting
[SDK, RxSDK] signup() Install
Initialize
Permission Prerequisite Kakao Login User consent
Required Register platforms
Activate Kakao Login
Required -
Note

The Manual signup API is only for the app with the Auto-link option disabled. Before using this API, check out when to use this API and the cautions in REST API.

The Manual signup API manually links a user with your app to complete signup when the Auto-link is disabled.

To figure out if the currently logged-in user needs to be linked with your app, check the value of hasSignedUp in the response of the Retrieving user information API and handle each case:

  • true: The user is already linked with your app. You do not need to call the Manual signup API.
  • false: The user is not linked with your app. You must call signup() to link the user with your app manually.
  • null: Your app is using the Auto-link feature. You do not need to call the Manual signup API.
Kotlin
RxKotlin
UserApiClient.instance.me { user, error ->
    if (error != null) {
        Log.e(TAG, "Retrieving user information fails", error)
    } else {
        Log.i(TAG, "Retrieving user information succeeds" +
                "\nService user ID: ${user.id}" +
                "\nLinked status: ${user.hasSignedUp}")
    }
}
var disposables = CompositeDisposable()

UserApiClient.rx.me()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe({ user ->
        Log.i(TAG, "Retrieving user information succeeds" +
                "\nService user ID: ${user.id}" +
                "\nLinked status: ${user.hasSignedUp}")
    }, { error ->
        Log.e(TAG, "Retrieving user information fails", error)
    }).addTo(disposables)

Request

If the return value of hasSignedUp is false and the user is ready to sign up, Call signup() method to complete the signup.

Response

If the request is successful, the user's service ID is returned.

To check the request result, request the Retrieving user information API again and check the value of hasSignedUp because the user's linked status is not provided even when the request is successful.

Sample

Kotlin
RxKotlin
UserApiClient.instance.signup { error ->
    if (error != null) {
        Log.e(TAG, "signup fails", error)
    } else {
        Log.i(TAG, "signup succeeds")
    }
}
var disposables = CompositeDisposable()

UserApiClient.rx.signup()
        .subscribeOn(Schedulers.io())
        .subscribe(Action { showSnackbar("signup() succeeds") }, onError).addTo(disposables)

Additional feature

Update additional information

If you want to store the user's information when the user is linked to your app, pass properties.