사용자 관리

사용자 관리는 카카오 플랫폼 서비스에서 제공하는 핵심 기능 중 하나입니다. 사용자 관리는 쉽고 빠른 방법으로 사용자의 계정을 카카오 플랫폼과 연결해줍니다. 해당 기능을 통하여 안전하고 보다 더 강력한 참여형 사용환경의 앱을 만들 수 있습니다.

  • 시작하기 전에
    사용자 관리 기능을 연동하기 전에 필요한 앱 설정 항목과 특징을 설명합니다.

사용자 관리의 상세 기능은 다음과 같습니다.

  • 로그인
    카카오계정을 통한 빠르고 간편한 로그인 기능을 지원합니다.
  • 로그아웃
    로그인된 사용자의 세션 연결을 해제합니다.
  • 앱 연결
    로그인한 사용자와 앱을 카카오 플랫폼에 연결합니다. 사용자가 앱 가입/등록 요청을 하는 경우와 비슷합니다.
  • 앱 연결 해제
    카카오 플랫폼에 연결된 사용자와 앱의 연결을 영구 해제합니다. 사용자가 앱 탈퇴 요청을 하는 경우와 비슷합니다.
  • 사용자 정보 요청
    사용자에 대한 정보를 얻어 올 수 있습니다. 해당 기능을 사용하기 위해서는 로그인 및 앱 연결이 되어 있어야 합니다.
  • 사용자 정보 저장
    사용자에 대한 특정 정보를 저장할 수 있습니다. 해당 기능을 사용하기 위해서는 로그인 및 앱 연결이 되어 있어야 합니다.
  • 토큰 정보 얻기
    사용자 토큰의 정보를 얻고, 해당 토큰의 유효성을 검증합니다.

시작하기 전에

사용자 관리 기능을 사용하기 위해서 설정 > 사용자 관리에서 추가 설정이 필요합니다.

dev_021.png

  • 첫째, 사용ON 해야합니다

  • 둘째, 앱 연동 설정 > 자동 가입 을 선택할 수 있습니다.

    카카오 플랫폼 서비스는 편의를 위해 자동 앱 연결 기능을 제공합니다. 해당 설정이 활성화되어 있을 경우 최초 로그인시 자동으로 앱 연결이 호출되므로 별도의 앱 연결 과정을 수행할 필요는 없습니다.

    사용자가 서비스에 최초 로그인하여 토큰을 얻는 순간과 실제 서비스 가입 시점이 동일하지 않는 경우(예를 들어, 서비스 내에 가입절차가 별도로 있거나 서비스약관동의 등의 절차가 별도로 있는 경우) 반드시 자동 가입 옵션을 끄셔야 합니다. 자동 가입 옵션을 끈 경우 사용자 최초 로그인 후에 명시적으로 가입API를 호출해야 사용자 가입이 완료됩니다.

    실제 서비스 가입하는 순간이 다름에도 불구 하고 자동 가입 옵션을 켜서 사용하는 경우는 사용자에게 혼란을 줄 수 있습니다. 예를 들어, 서비스 가입 과정 중에 이탈한 경우 카카오 로그인이 완료된 상태라면 연결된 앱관리에 해당 앱이 나타나게 됩니다. 이런 과정은 서비스를 탈퇴하고 난 후 탈퇴가 잘 되었는 지 확인차 로그인을 해보는 과정에서 자주 겪게 됩니다.

    사용자는 카카오계정으로 연결된 앱의 정보를 카카오톡이나 카카오스토리 내에 존재하는 카카오계정의 연결된 앱관리 페이지에서 확인할 수 있습니다.

  • 셋째, 앱 연동 설정 > 카카오 계정 연동 을 선택할 수 있습니다.

    기본으로 제공되는 사용자 정보로 카카오톡 서비스 정보를 사용할지, 카카오스토리 서비스 정보를 사용할지, 두 서비스 모두 사용하는 사용자의 경우는 어느 서비스 정보에 우선순위를 둘지를 결정합니다. 기본으로 추가되어 있는 사용자 프로퍼티로는 nickname, profile_image, thumbnail_image가 있습니다.

    앱 연결 과정에서 최초 한번만 카카오톡 또는 카카오스토리 서비스와 동기화 연동을 하게 됩니다. 사용자가 해당 정보를 카카오톡 또는 카카오스토리에서 변경하였어도 추후 변경된 데이타는 반영되지 않습니다.

    카카오톡 또는 카카오스토리와의 동기화 연동 기능을 사용하지 않도록 설정되어 있을 경우, 해당 부가정보는 빈값으로 채워져 있습니다. 이 기본 부가정보는 사용자 정보 저장 기능을 통해 다른 데이타로 언제든 교체가 가능합니다.

  • 넷째, 가입시 추가하고 싶은 사용자 정보를 사용자 목록 및 프로퍼티 관리 메뉴를 통해 추가할 수 있습니다.

    커스텀 사용자 정보 컬럼은 5개 이하로 제한 하고, 각 커스텀 사용자 정보 값은 160자 이내로 권장합니다. 실제로 사용자의 프로퍼티는 앱 연결 시에 추가 가능합니다. 또한 사용자 정보 저장 기능을 통해서도 추가 가능합니다.

  • 다섯째, 서비스에서 사용할 API에서 요구하는 동의항목을 선택하고, 해당 API를 호출하는 목적, 즉 해당 정보의 수집 목적을 설정해야 합니다.

    입력한 수집목적의 내용과 실제 서비스에서 해당 개인 정보를 사용하는 목적이 다를 경우 API서비스의 거부 사유가 될 수 있습니다. 카카오계정 이메일을 사용하기 위해서는 여기에서 이메일 사용을 설정해야 합니다.

  • 여섯째, 서비스를 운영하는 곳이 국외라면 사용자 관리 > 개인정보 국외이전 에서 개인정보가 저장되는 국가의 정보를 입력해야 합니다.

로그인

카카오계정을 이용하여 빠르고 간편하게 로그인을 할 수 있습니다.

일반적으로 사용자는 카카오계정으로 로그인 버튼을 클릭함으로서 카카오계정 기반의 로그인을 수행합니다.

  1. 카카오톡이 설치된 기기에서는 카카오톡 앱과 연결된 카카오계정을 이용한 간편 로그인이 제공됩니다.

    • 카카오계정이 연결되어 있는 경우: 카카오톡의 카카오계정을 이용합니다.
    • 카카오계정 연결이 되어 있지 않은 경우: Native 로그인 창을 통해 카카오계정 연결을 수행하게 됩니다.
  2. 카카오스토리 버전 2.6.0 이상이 설치된 기기에서는 로그인된 카카오계정을 이용한 간편 로그인이 제공됩니다.

  3. 카카오톡이나 카카오스토리가 설치되어 있지 않는 기기에서는 웹뷰를 통해 카카오계정 연결만 제공됩니다.

위와 같이 세가지 옵션 중에 본인의 앱의 성격에 따라 옵션을 선택할 수 있습니다. 선택하는 방법은 아래 코드 샘플을 참고하세요.

해당 로그인 기능은 OAuth 2.0을 지원합니다. 다음은 카카오 플랫폼 서비스에서 제공하는 가장 일반적인 OAuth 인증의 과정입니다.

1. 사용자는 카카오계정으로 로그인 버튼을 클릭합니다.
2. 카카오톡 앱에 연결된 카카오계정의 자격정보(Credentials)를 통해 사용자를 인식합니다.
3. 자격정보가 올바르다면 사용자(Resource Owner)로부터 접근 자원에 대한 동의/허가를 얻습니다.
4. 위 3까지 성공적으로 수행되었다면 인증 코드(Authorization Code)가 발급됩니다. 해당 인증 코드는 Redirection URI를 기반으로 Third 앱에 전달됩니다.
5. Third 앱에서는 전달받은 인증 코드를 기반으로 사용자 토큰(Access Token, Refresh Token)을 요청하고 얻게 됩니다.

사용자 토큰은 카카오 플랫폼 서비스에서 제공하는 로그인 기반의 기능을 사용하는데 있어 중요한 키로 사용됩니다. OAuth 2.0의 보다 자세한 내용은 여기를 참고하세요. 위의 복잡한 과정들은 Kakao SDK가 많은 부분 담당하고 있으며, 이를 어떻게 사용하는지에 대해 다음에서 설명합니다.

로그인 사용법

1. KakaoSDK를 사용하기 위해선 SDK와 Application을 연결해 주어야 하며, 이때 사용되는 객체는 KakaoAdapter입니다. KakaoAdapter를 통해서 SDK에 필요한 정보를 제공해 주어야 하며 각각 IApplicationConfigISessionConfig를 구현해 주어야 합니다.

IApplicationConfig

Application이 가지고있는 정보를 얻기위한 interface.

Name Return Description
getApplicationContext Context Application Context

ISessionConfig

로그인을 위해 Session을 생성하기 위해 필요한 옵션을 얻기위한 abstract class. 기본 설정은 KakaoAdapter에 정의되어있으며, 설정 변경이 필요한 경우 상속해서 사용할 수 있다.

Name Return Description
getAuthTypes AuthType 로그인시 인증받을 타입을 지정한다. 지정하지 않을 시 가능한 모든 옵션이 지정된다.
isUsingWebviewTimer boolean SDK 로그인시 사용되는 WebView에서 pause와 resume시에 Timer를 설정하여 CPU소모를 절약한다. true 를 리턴할경우 webview로그인을 사용하는 화면서 모든 webview에 onPause와 onResume 시에 Timer를 설정해 주어야 한다. 지정하지 않을 시 false로 설정된다.
isSecureMode boolean 로그인시 access token과 refresh token을 저장할 때의 암호화 여부를 결정한다.
getApprovalType ApprovalType 일반 사용자가 아닌 Kakao와 제휴된 앱에서 사용되는 값으로, 값을 채워주지 않을경우 ApprovalType.INDIVIDUAL 값을 사용하게 된다.
isSaveFormData boolean Kakao SDK 에서 사용되는 WebView에서 email 입력폼에서 data를 save할지여부를 결정한다. Default true.

AuthType

Kakao SDK로그인을 하는 방식에 대한 Enum class

Name Value Description
KAKAO_TALK 0 kakaotalk으로 login을 하고 싶을때 지정.
KAKAO_STORY 1 kakaostory으로 login을 하고 싶을때 지정.
KAKAO_ACCOUNT 2 웹뷰 Dialog를 통해 카카오 계정연결을 제공하고 싶을경우 지정.
KAKAO_TALK_EXCLUDE_NATIVE_LOGIN 3 카카오톡으로만 로그인을 유도하고 싶으면서 계정이 없을때 계정생성을 위한 버튼도 같이 제공을 하고 싶다면 지정.
KAKAO_TALK과 중복 지정불가.
KAKAO_LOGIN_ALL 4 모든 로그인방식을 사용하고 싶을때 지정.

UserProfile

MeResponseCallback을 통해 성공시 onSuccess의 Param으로 UserProfile 정보를 넘겨준다.

SDK 내부적으로 저장소에 Cache를 한다. loadFromCache() method를 통해 저장되어있는 UserProfile 정보를 얻어갈 수 있다.

Field Value Type Description
id long 인증 여부를 확인하는 user의 id
nickname String 사용자 별명
thumbnailImagePath String 110px 110px(톡에서 가지고 온 경우) 또는 160px 160px(스토리에서 가지고 온 경우) 크기의 사용자의 썸네일 프로필 이미지 경로
profileImagePath String 480px 480px ~ 1024px 1024px 크기의 사용자의 프로필 이미지 경로
properties Map param으로 propertyKeys를 준 경우는 해당 propertyKey에 해당 하는 값들만 내려감(reserved properties + custom properties)
public class GlobalApplication extends Application {
    private static class KakaoSDKAdapter extends KakaoAdapter {
        /**
         * Session Config에 대해서는 default값들이 존재한다.
         * 필요한 상황에서만 override해서 사용하면 됨.
         * @return Session의 설정값.
         */
        @Override
        public ISessionConfig getSessionConfig() {
            return new ISessionConfig() {
                @Override
                public AuthType[] getAuthTypes() {
                    return new AuthType[] {AuthType.KAKAO_LOGIN_ALL};
                }

                @Override
                public boolean isUsingWebviewTimer() {
                    return false;
                }

                @Override
                public boolean isSecureMode() {
                    return false;
                }

                @Override
                public ApprovalType getApprovalType() {
                    return ApprovalType.INDIVIDUAL;
                }

                @Override
                public boolean isSaveFormData() {
                    return true;
                }
            };
        }

        @Override
        public IApplicationConfig getApplicationConfig() {
            return new IApplicationConfig() {
                @Override
                public Context getApplicationContext() {
                    return GlobalApplication.getGlobalApplicationContext();
                }
            };
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();

        KakaoSDK.init(new KakaoSDKAdapter());

        ...
    }
    ...
}

2. LoginButton는 로그인 버튼을 포함하는 FrameLayout입니다. 이를 로그인 창 레이아웃(layout) 파일에 추가합니다.

<com.kakao.usermgmt.LoginButton
    android:id="@+id/com_kakao_login"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:layout_marginBottom="30dp"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"/>

3. 로그인 Activity의 예제 코드로 kakao-open-android-sdk-sample 에 포함된 com.kakao.sdk.sample.common.SampleLoginActivity 입니다.

public class SampleLoginActivity extends Activity {
    private SessionCallback callback;

    /**
     * 로그인 버튼을 클릭 했을시 access token을 요청하도록 설정한다.
     *
     * @param savedInstanceState 기존 session 정보가 저장된 객체
     */
    @Override
    protected void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_common_kakao_login);

        callback = new SessionCallback();
        Session.getCurrentSession().addCallback(callback);
        Session.getCurrentSession().checkAndImplicitOpen();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (Session.getCurrentSession().handleActivityResult(requestCode, resultCode, data)) {
            return;
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Session.getCurrentSession().removeCallback(callback);
    }

    private class SessionCallback implements ISessionCallback {

        @Override
        public void onSessionOpened() {
            redirectSignupActivity();
        }

        @Override
        public void onSessionOpenFailed(KakaoException exception) {
            if(exception != null) {
                Logger.e(exception);
            }
        }
    }

    protected void redirectSignupActivity() {
        final Intent intent = new Intent(this, SampleSignupActivity.class);
        startActivity(intent);
        finish();
    }
}
Name Param Description
onCreate Bundle 로그인 Activity가 생성될 때 로그인 버튼을 찾아오고, 세션의 상태가 변경될 때 불리는 세션 콜백을 추가해 줍니다.세션이 닫혀 있는지, 이미 오픈되어 있는지, 갱신이 가능한지에 따라 다른 액션을 취합니다.예제에서는 닫혀 있으면 로그인 버튼을 보여주고, 열려 있으면 로그인 버튼을 보여주지 않으며, 갱신이 가능하면 갱신까지 시켜줍니다.
onDestroy NONE 세션의 상태가 변경될 때 불리는 세션 콜백을 삭제합니다.
onActivityResult (int, int, Intent) 로그인 activity를 이용하여 sdk에서 필요로 하는 activity를 띄우기 때문에 해당 결과를 세션에도 넘겨줘서 처리할 수 있도록 Session#handleActivityResult를 호출해 줍니다.

ISessionCallback

세션의 체크시 상태 변경에 따른 콜백. 세션이 오픈되었을 때, 세션이 닫혔을 때 세션 콜백을 넘기게 된다. 예제에서는 SessionCallback이 상속받아 구현되어있다.

Name Param Description
onSessionOpened NONE access token을 성공적으로 발급 받아 valid access token을 가지고 있는 상태. 일반적으로 로그인 후의 다음 activity로 이동한다.
onSessionOpenFailed KakaoException memory와 cache에 session 정보가 전혀 없는 상태. 일반적으로 로그인 버튼이 보이고 사용자가 클릭시 동의를 받아 access token 요청을 시도한다.

Client secret 기능

카카오 로그인에서는 보안 수준을 강화하기 위하여 OAuth 클라이언트 시크릿 기능을 제공합니다.

클라이언트 시크릿 기능은 개발자 웹사이트의 내 애플리케이션 설정 > 일반 > Client Secret 메뉴를 통해 발급 및 활성화를 수행할 수 있습니다. 클라이언트 시크릿 기능을 사용하려면 앱의 AndroidManifest.xml에 다음과 같이 클라이언트 시크릿을 설정해야 합니다.

<uses-permission android:name="android.permission.INTERNET" />

<application>
    ...
    <meta-data
        android:name="com.kakao.sdk.ClientSecret"
        android:value="<kakao client secret value>"/>
    ...
</application>

[결과 예시]

다음은 이해를 돕기위한 로그인 과정의 결과 예시입니다.

login_button.png

카카오톡 앱이나 2.6.0이상 버젼의 카카오스토리 앱이 설치되어 있다면 카카오톡으로 간편로그인을 할지, 카카오스토리로 간편로그인 할지, 다른 계정을 직접 입력해서 로그인할지 선택할 수 있는 창이 뜨게 됩니다. 해당 버젼 이하의 앱이 설치되어 있거나 앱이 설치되어 있지 않다면 선택창에서 제외되고, 두 앱 모두 존재하지 않으면 선택창이 뜨지 않고 바로 3번 즉, 다른 계정으로 로그인을 선택한 경우와 같은 화면이 보이게 됩니다.

choose_account_dialog.png

1. 카카오톡으로 간편로그인을 선택한 경우
1-1. 카카오계정이 연결되어 있는 경우, 접근 자원에 대한 동의/허가를 위한 화면이 나타납니다.

a_006.png

1-2. 카카오계정 연결이 되어 있지 않은 경우, 아이디와 비밀번호를 요구하는 화면이 나타납니다. 자격 정보(Credentials)에 대한 검증이 통과하면 접근 자원에 대한 동의/허가를 위한 화면이 나타납니다.

a_007.png a_008.png

2. 카카오스토리로 간편로그인을 선택한 경우
2-1. 로그인이 되어 있는 경우, 1-1과 같은 접근 자원에 대한 동의/허가를 위한 화면이 나타납니다.
2-2. 로그아웃 되어 있는 경우, 3번 화면으로 연결됩니다.

3. 다른 계정으로 로그인을 선택한 경우 웹뷰를 통해 아이디와 비밀번호를 요구하는 화면이 나타납니다. 자격 정보(Credentials)에 대한 검증이 통과하면 접근 자원에 대한 동의/허가를 위한 화면이 나타납니다.

a_009.png a_010.png

로그아웃

사용자의 기기에서 앱과 카카오계정과의 세션 연결을 해제하는 기능입니다.

로그인 기능은 멀티디바이스를 지원합니다. 만약 사용자가 여러 기기에서 하나의 같은 카카오계정으로 로그인 후 로그아웃을 수행한다면, 해당 로그아웃을 수행한 기기에서만 세션 연결이 해제됩니다.


로그아웃 요청의 결과에 따른 콜백(LogoutResponseCallback)을 구현하고, UserManagement#requestLogout API를 호출합니다.

LogoutResponseCallback

Name Param Description
onCompleteLogout NONE 로그아웃을 성공한 경우 불립니다. 서버에 로그아웃 도달과 무관하게 항상 성공을 하며, 예제에서는 로그인 창으로 이동시킵니다.
private void onClickLogout() {
    UserManagement.requestLogout(new LogoutResponseCallback() {
        @Override
        public void onCompleteLogout() {
            redirectLoginActivity();
        }
    });
}

앱 연결

앱 연결은 로그인한 사용자와 앱을 카카오 플랫폼에 연결함으로서 일반적으로 사용자가 앱 가입/등록 요청을 하는 경우와 비슷합니다. 카카오 플랫폼 서비스를 올바로 사용하기 위해서는 로그인 후 반드시 앱 연결이 선행되어야 하며, 최초 한번만 수행가능합니다. 앱 연결이 올바로 수행되면 해당 사용자에 대한 고유한 아이디(ID)가 부여됩니다.

로그인 수행 후, 사용자 정보를 호출하였으나 가입이 안된 상태라 실패한다면 가입 창을 띄워줘야 합니다. 가입시에 개별 사용자에 대한 특정 부가정보를 저장하고 싶은 경우 가입과 함께 사용자 정보를 저장할 수 있습니다. 이는 가입 후에 사용자 정보 저장을 통해 업데이트 될 수 있습니다.

기본으로 추가되어 있는 사용자 정보로는 nickname, profile_image, thumbnail_image가 있습니다. 이 세개의 parmeter중 하나도 채우지 않고 요청하면, 설정 > 사용자 관리 > 앱 연동 설정 > 카카오 계정 연동 메뉴의 우선순위에 의해 카카오톡 혹은 카카오스토리 프로필이 자동으로 들어가게 됩니다. 위의 세개의 parameter 중 일부(1개 혹은 2개)만 parameter로 보내면 남은 정보는 카카오 계정 연동 우선순위에 따라 카카오톡이나 카카오스토리 정보로 채워지게 됩니다. 때문에, profile_image, thumbnail_image 중 하나만 parameter로 채우게 되면, 두 이미지가 달라질 수 있습니다(parameter로 보낸 이미지와, 카카오톡 혹은 카카오 스토리의 이미지가 다를 경우). 따라서, profile_image 혹은 thumbnail_image를 parameter로 요청할 땐 꼭 profile_image, thumbnail_image의 쌍으로 요청하는 것을 권장합니다.

다음은 기본 사용자 정보 중 nickname과 커스텀 사용자 정보 age와 함께 앱 연결 요청하는 예제 코드입니다. 커스텀 사용자 정보 age 항목은 대쉬보드의 설정 > 사용자 관리 메뉴에 미리 선언되어 있어야 합니다.

가입페이지에서 사용자가 입력한 정보 Map과 앱연결 요청의 결과에 따른 콜백(SignupResponseCallback)을 구현하여, UserManagement#requestSignup API를 호출합니다.

SignupResponseCallback

Name Param Description
onSuccess Long 앱연결을 성공한 경우로 앱연결된 사용자 ID를 받습니다.
onSessionClosed ErrorResult 세션이 닫혀 실패한 경우로 에러 결과를 받습니다.
onFailure ErrorResult 앱연결이 실패한 경우로 에러 결과를 받습니다.
private void onClickSignup() {
    final Map<String, String> properties = new HashMap<String, String>();
    properties.put("nickname", "leo");
    properties.put("age", "33");

    UserManagement.requestSignup(new SignupResponseCallback() {
        @Override
        public void onSuccess(final long userId) {
            redirectMainActivity();
        }
        @Override
        public void onSessionClosed(final ErrorResult errorResult) {
            redirectLoginActivity();
        }
        @Override
        public void onFailure(final ErrorResult errorResult) {
            Logger.e(this, "failed to sign up. msg = " + errorResult);
        }
    }, properties);
}

properties 정보는 가입 후에도 사용자 정보 저장을 통해 업데이트 될 수 있습니다.

앱 연결 해제

앱 연결 해제는 카카오 플랫폼에 연결된 사용자와 앱의 연결을 영구 해제함으로서 일반적으로 사용자가 앱 탈퇴 요청을 하는 경우와 비슷합니다. 앱 연결 해제가 수행된 사용자는 영구적으로 복구가 불가능하며 카카오 플랫폼 서비스를 더이상 사용할 수 없습니다. 단, 다시 앱 연결을 통해 새로운 데이터로 카카오 플랫폼 서비스를 이용할 수는 있습니다.

앱 연결 해제를 수행할 경우 카카오 플랫폼에서 관리하는 해당 사용자의 데이터는 모두 지워집니다. 단, Third앱에서 저장하는 데이터의 경우 카카오 플랫폼 서비스에서는 책임을 질 수 없습니다. 이는 Third앱에서 지워야 할 의무를 가집니다(보다 자세한 내용은 정책 및 약관을 참고하세요). 이것이 흔히 말하는 앱 탈퇴와 앱 연결 해제와의 차이점입니다.

앱 연결 해제의 결과에 따른 콜백(UnlinkResponseCallback)을 구현하고, UserManagement#requestUnlink를 호출합니다.

예제에서는 앱연결 해제가 성공되면 사용자의 정보가 모두 삭제되기 때문에 한번 더 확인하기 위해 확인창을 띄웁니다.

UnlinkResponseCallback

Name Param Description
onSuccess Long 앱 연결 해제을 성공한 경우로 앱 연결 해제된 사용자 ID를 받습니다.
onSessionClosed ErrorResult 세션이 닫혀 실패한 경우로 에러 결과를 받습니다.
onFailure ErrorResult 앱 연결 해제에 실패한 경우로 에러 결과를 받습니다.

로그아웃 요청과는 달리 "앱 연결 해제" 요청 성공시에만 세션이 삭제됩니다. 따라서 실패시에 기존 세션을 이용하여 재시도 등을 할 수 있습니다.

private void onClickUnlink() {
    final String appendMessage = getString(R.string.com_kakao_confirm_unlink);
        new AlertDialog.Builder(this)
            .setMessage(appendMessage)
            .setPositiveButton(getString(R.string.com_kakao_ok_button),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        UserManagement.requestUnlink(new UnLinkResponseCallback() {
                            @Override
                            public void onFailure(ErrorResult errorResult) {
                                Logger.e(errorResult.toString());
                            }

                            @Override
                            public void onSessionClosed(ErrorResult errorResult) {
                                redirectLoginActivity();
                            }

                            @Override
                            public void onNotSignedUp() {
                                redirectSignupActivity();
                            }

                            @Override
                            public void onSuccess(Long userId) {
                                redirectLoginActivity();
                            }
                        });
                        dialog.dismiss();
                    }
                })
            .setNegativeButton(getString(R.string.com_kakao_cancel_button),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                }).show();

}

사용자 정보 요청

사용자 정보 요청은 사용자에 대한 아이디(ID) 와 카카오계정 이메일(email) 및 개별 상세 정보를 얻어 올 수 있는 기능입니다. 해당 기능을 사용하기 위해서는 성공적인 로그인 후에 얻을 수 있는 사용자 토큰이 필요합니다. 또한 앱 연결이 전제가 되어 있어야 합니다.

사용자 아이디(ID)의 경우 앱 연결 과정에서 발급하는 앱별 사용자의 고유 아이디입니다. 해당 아이디를 통해 사용자를 앱에서 식별 가능하며, 앱 연결 해제를 하지 않는 한 같은 사용자는 같은 값으로 계속 유지됩니다.

카카오계정 이메일을 사용하기 위해서는 서비스에서 이메일을 사용하도록 설정해야 하고 사용자의 동의도 필요합니다. 개발자 웹사이트에서 제공하는 대쉬보드의 설정 > 사용자 관리 > 동의항목 관리 에서 이메일 항목을 필수 로 설정하고 이메일을 수집하는 목적을 정확하게 입력해야 합니다. 입력한 수집목적의 내용과 실제 서비스에서 해당 개인 정보를 사용하는 목적이 다를 경우 API서비스의 거부 사유가 될 수 있습니다.

카카오계정 이메일을 수집하여 사용할때 다음 내용을 주의하세요.

사용자가 카카오계정의 이메일을 인증받지 않은 경우 이메일은 변경될 수 있습니다.

카카오 플랫폼 서비스에서는 편의를 위해 카카오톡 또는 카카오스토리 서비스와 연동하여 사용자별 다음과 같은 기본 부가정보를 제공합니다.

Name Description
kaccount_email 사용자 카카오계정의 이메일
kaccount_email_verified 인증받은 카카오계정 이메일인지 여부
인증받지 않은 이메일은 변경될 수 있습니다.
nickname 카카오톡 또는 카카오스토리의 닉네임 정보
profile_image 640px * 640px 크기의 카카오톡 또는 카카오스토리의 프로필 이미지 URL (2017/08/22 이전 가입자에 대해서는 480px * 480px ~ 1024px * 1024px 크기를 가질 수 있음)
thumbnail_image 110px * 110px 크기의 카카오톡 또는 카카오스토리의 썸네일 프로필 이미지 URL (2017/08/22 이전 가입자에 대해서는 160px * 213px 크기를 가질 수 있음)

사용자 정보 요청의 결과에 따른 콜백(MeResponseCallback)을 구현하고, UserManagement#requestMe API를 호출합니다. 특정 프로퍼티만 받고 싶거나, 이미지 url을 https로 받고 싶은 경우에는 UserManagement#requestMe(boolean) API를 호출합니다

MeResponseCallback

Name Param Description
onSuccess UserProfile 사용자 정보 요청이 성공한 경우로 사용자 정보 객체를 받습니다.
onNotSignedUp NONE 사용자가 가입된 상태가 아니여서 실패한 경우입니다.
onSessionClosed ErrorResult 세션이 닫혀 실패한 경우로 에러 결과를 받습니다.
onFailure ErrorResult 가입이 안된 경우와 세션이 닫힌 경우를 제외한 다른 이유로 요청이 실패한 경우의 콜백입니다.
private void requestMe() {
    UserManagement.requestMe(new MeResponseCallback() {
        @Override
        public void onFailure(ErrorResult errorResult) {
            String message = "failed to get user info. msg=" + errorResult;
            Logger.d(message);

            redirectLoginActivity();
        }

        @Override
        public void onSessionClosed(ErrorResult errorResult) {
            redirectLoginActivity();
        }

        @Override
        public void onSuccess(UserProfile userProfile) {
            Logger.d("UserProfile : " + userProfile);
            redirectMainActivity();
        }

        @Override
        public void onNotSignedUp() {
            showSignup();
        }
    });
}

추가적으로 이미 서비스 중인 앱에서 사용자의 이메일을 수집하고 싶은 경우에는 아래 가이드를 따릅니다.

이메일 항목에 동의 없이 가입한 사용자의 이메일을 수집하기 위해서는 사용자의 동적동의가 필요합니다. 위와 같은 방법으로 API를 호출하게 되면 이메일이 포함되어 있지 않은 프로필 값이 내려가기 때문에 유의하시기 바랍니다.

이메일이 필요한 시점에 다음과 같이 사용자의 이메일 정보를 요청해야합니다. 이 때 이메일 뿐만 아니라 필요한 property들을 모두 명시해줘야 합니다.

private void requestMe() {
  List<String> propertyKeys = new ArrayList<String>();
  propertyKeys.add("kaccount_email");
  propertyKeys.add("nickname");
  propertyKeys.add("profile_image");
  propertyKeys.add("thumbnail_image");

  UserManagement.requestMe(new MeResponseCallback() {
      @Override
      public void onFailure(ErrorResult errorResult) {
          String message = "failed to get user info. msg=" + errorResult;
          Logger.d(message);

          redirectLoginActivity();
      }

      @Override
      public void onSessionClosed(ErrorResult errorResult) {
          redirectLoginActivity();
      }

      @Override
      public void onSuccess(UserProfile userProfile) {
          Logger.d("UserProfile : " + userProfile);
          redirectMainActivity();
      }

      @Override
      public void onNotSignedUp() {
          showSignup();
      }
  }, propertyKeys, false);
}

사용자 정보 저장

사용자 정보 저장은 개별 사용자에 대한 특정 부가정보를 저장할 수 있는 기능입니다. 카카오 플랫폼 서비스에서 제공하는 기본 부가정보 외에도, 개발자 웹사이트를 통해 앱별 커스텀한 정보를 선언하여 유저별 데이터를 저장할 수 있습니다. 해당 기능을 사용하기 위해서는 성공적인 로그인 후에 얻을 수 있는 사용자 토큰이 필요합니다. 또한 앱 연결이 전제가 되어 있어야 합니다.

  • 사용자 정보 저장 기능으로 수정할 수 없는 사용자의 정보도 존재합니다. 예를 들어 사용자의 아이디(ID)는 수정될 수 없습니다.
  • profile_image와 thumbnail_image 둘 중 하나만 저장 요청하여도 640px * 640px, 110px * 110px 크기로 각각 저장됩니다. 두 이미지를 함께 저장 요청한 경우 profile_image를 원본으로 각 크기로 저장됩니다.

다음은 사용자 정보에 기본 부가정보 중 nickname과 커스텀 정보 age을 저장하는 예제 코드입니다. 커스텀 정보 age 항목은 대쉬보드의 설정 > 사용자 관리 메뉴에 미리 선언되어 있어야 합니다.

사용자 정보 저장은 사용자가 입력한 정보 Map과 사용자 정보 저장 요청의 결과에 따른 콜백ApiResponseCallback을 가지고 UserManagement#requestUpdateProfile API를 호출합니다.

ApiResponseCallback

Name Param Description
onSuccess Long 사용자 정보 저장을 성공한 경우로 앱연결된 사용자 ID를 받습니다.
onSessionClosed ErrorResult 세션이 닫혀 실패한 경우로 에러 결과를 받습니다.
onFailure ErrorResult 사용자 정보 저장이 실패한 경우로 에러 결과를 받습니다.
private void requestUpdateProfile() {
    final Map<String, String> properties = new HashMap<String, String>();
    properties.put("nickname", "Leo");
    properties.put("age", "33");

    UserManagement.requestUpdateProfile(new UsermgmtResponseCallback<Long>() {
        @Override
        public void onSuccess(Long userId) {
            userProfile.updateUserProfile(properties);
            if (userProfile != null) {
                userProfile.saveUserToCache();
            }
            Logger.d("succeeded to update user profile" + userProfile);
        }

        @Override
        public void onNotSignedUp() {
            redirectSignupActivity(self);
        }

        @Override
        public void onFailure(ErrorResult errorResult) {
            String message = "failed to get user info. msg=" + errorResult;
            Logger.e(message);
        }

        @Override
        public void onSessionClosed(ErrorResult errorResult) {
            redirectLoginActivity(self);
        }

    }, properties);
}

토큰 정보 얻기

로그인을 통해 얻은 사용자 토큰의 정보를 얻는 기능입니다. 가입전에 해당 토큰의 사용자 id를 얻거나, 주기적인 토큰 유효성 검증시 사용할 수 있습니다. 사용자 토큰이 유효할 경우 토큰의 정보를 응답으로 받을 수 있으며, 토큰이 유효하지 않을 경우 상황에 맞는 오류를 받을 수 있습니다. 다른 API와 달리 가입전에도 호출할 수 있어, 미가입인 경우에 onNotSignedUp() 콜백이 불리지 않습니다.

다음은 사용자 토큰의 정보를 얻는 예제 코드입니다.

    private void requestAccessTokenInfo() {
        AuthService.requestAccessTokenInfo(new ApiResponseCallback<AccessTokenInfoResponse>() {
            @Override
            public void onSessionClosed(ErrorResult errorResult) {
                redirectLoginActivity(self);
            }

            @Override
            public void onNotSignedUp() {
                // not happened
            }

            @Override
            public void onFailure(ErrorResult errorResult) {
                Logger.e("failed to get access token info. msg=" + errorResult);
            }

            @Override
            public void onSuccess(AccessTokenInfoResponse accessTokenInfoResponse) {
                long userId = accessTokenInfoResponse.getUserId();
                Logger.d("this access token is for userId=" + userId);

                long expiresInMilis = accessTokenInfoResponse.getExpiresInMillis();
                Logger.d("this access token expires after " + expiresInMilis + " milliseconds.");
            }
        });
    }

API요청 공통 Response 및 Error

모든 API요청에 대한 base callback이 정의되어있다. 모든 API responseCallback은 ApiResponseCallback을 상속받아 구현이 되어있으며, ApiResponseCallback에서의 callback에 대한 처리를 해주어야 한다.

ApiResponseCallback

API 요청시 반환되는 공통 Response

Name Return Param Description
onNotSignedUp void NONE 세션 오픈은 성공했으나 사용자 정보 요청 결과 사용자 가입이 안된 상태로 자동 가입 앱이 아닌 경우에만 호출된다
onSessionClosed void ErrorResult 세션이 닫혔을때 불리는 callback
onFailure void ErrorResult API 요청이 실패했을경우 불린다.
onSuccess void T request에 대한 result
onDidStart void NONE Request시작시에 불린다
onDidEnd void NONE Request 끝나고 불린다

ErrorResult

API 요청시 반환되는 Error class

Name Type Description
getErrorCode ErrorCode 에러코드를 반환
getErrorMessage String 에러메세지를 반환
getHttpStatus int HttpStatus를 반환

에러코드

API ErrorCode 참조

Code 상태 설명
-1 INTERNAL_ERROR_CODE 서버에서 처리 중 에러 발생(internal error)
-2 INVALID_PARAM_CODE 필수 인자가 포함되지 않은 경우/호출 인자값이 적절한 데이타 타입이 아니거나 허용된 범위를 벗어난 경우.
-4 BLOCKED_ACTION_CODE 계정 제재 또는 특정 서비스에서 해당 사용자의 제재로 인해 API 호출이 금지된 경우
-5 ACCESS_DENIED_CODE 앱에 해당 API에 대한 퍼미션이 없는 경우
-10 EXCEED_LIMIT_CODE 허용된 요청 회수가 초과한 경우
-101 NOT_REGISTERED_USER_CODE 가입자에게만 허용된 API에서 미가입자가 요청한 경우. (후처리 : 미가입자의 가입절차 후 재시도)
-102 ALREADY_REGISTERED_USER_CODE 미가입자에게만 허용된 API에서 가입자가 요청한 경우. (예. signup, 초대메시지 전송)
-103 NOT_EXIST_KAKAO_ACCOUNT_CODE 존재하지 않는 카카오계정에 대한 호출
-201 NOT_REGISTERED_PROPERTY_KEY_CODE 사용자 관리 API 호출시 파라미터가 부적절히 구성되었을 경우. 주로 개발자 웹사이트의 (내 애플리케이션 > 설정 > 사용자 관리)에서 사용자 정보의 설정과 요청의 파라미터가 불일치 할 경우 발생. (후처리 : 개발자 웹사이트에 등록한 프로퍼티 키값 확인하여 수정/새로등록 후 재시도)
-301 NOT_EXIST_APP_CODE 등록되지 않은 앱키의 요청 또는 존재하지 않는 앱으로의 요청
-302 NOT_EXIST_APP_CATEGORY_CODE 앱 카테고리가 등록되지 않은 앱으로 요청한 경우 발생한다.
-401 INVALID_TOKEN_CODE 앱키/토큰이 잘못된 경우. 예를 들어, 앱키가 존재하지 않거나(다시 생성한 경우 이전 앱키를 사용하고 있는 경우) agent 정보와 일치하지 않는 앱키 타입인 경우. 토큰이 만료된 경우. (후처리 : 앱키의 값과 타입을 확인. refresh token으로 토큰을 갱신 후 재시도)
-402 INVALID_SCOPE_CODE 해당 API에서 접근하는 리소스에 대해 사용자의 동의를 받지 않은 경우. (후처리 : 동의 페이지를 다시 띄워 동적으로 추가 리소스에 대한 동의를 받은 후 재시도)
-405 NEED_TO_AGE_AUTHENTICATION 앱에 설정된 연령인증 방법 또는 최소 연령을 만족하지 않은 사용자가 요청한 경우. (후처리 : 연령인증 페이지를 띄워 연령인증을 받은 후 재시도)
-501 NOT_EXIST_KAKAOTALK_USER_CODE 카카오톡 가입 사용자에게만 허용된 API에서 카카오톡 미가입 사용자가 요청한 경우. (예. 카카오톡 API)
-601 NOT_EXIST_KAKAOSTORY_USER_CODE 카카오스토리 가입 사용자에게만 허용된 API에서 카카오스토리 미가입 사용자가 요청한 경우. (예. 카카오스토리 API)
-602 EXCEED_MAX_UPLOAD_SIZE 카카오스토리 이미지 업로드시 최대 용량(현재 10MB)을 초과하였을 경우
-603 EXECUTION_TIMED_OUT 카카오스토리 이미지 업로드/스크랩 정보 요청시 타임아웃 발생
-604 INVALID_STORY_SCRAP_URL 카카오스토리에서 스크랩이 실패하였을 경우
-605 INVALID_STORY_ACTIVITY_ID 카카오스토리에 존재하지 않는 내스토리를 요청을 했을 경우
-606 EXCEED_MAX_UPLOAD_NUMBER 카카오스토리 이미지 업로드시, 최대 이미지 갯수(현재 5개. 단, gif 파일은 1개)를 초과하였을 경우
-701 NOT_EXIST_DEVELOPER_CODE 현재 존재하지 않는 개발자가 생성한 앱으로부터 요청이 들어온 경우
-776 AUTH_ERROR_CODE AUTH서버에서 발생하는 에러일때.
-901 NOT_EXIST_PUSH_TOKEN 등록된 푸시토큰이 없는 기기로 푸시 메시지를 보낸 경우
-9798 점검중

문제해결

시작하기를 진행하면서 어려움이 있거나, 샘플앱 등이 잘 실행되지 않는다면 사용자 관리 문제해결을 참고해 보세요.



Last Modified : 2017-08-22