오늘은 안드로이드 상에서 카카오톡 소셜 로그인 연동 기능에 대해 알아보겠습니다.
아래 사진은 제가 테스트를 위해 미리 구현 해둔 소셜 로그인 UI 화면 입니다.
먼저 카카오톡 소셜 로그인 기능을 구현하기 앞서
유저의 카카오톡 로그인을 통해 관리자가 획득할 수 있는 정보에 대해 알아보겠습니다.
#카카오톡 소셜 로그인시 획득 가능한 회원정보
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) |
출처 : https://developers.kakao.com/docs/android#사용자-관리
위의 내용 따라 사용 가능한 정보는 회원의 아이디,닉네임,프로필 이미지가 전부 입니다.
때문에 서비스의 성격에 따라 보통 이메일 혹은 전화번호를 추가로 입력 받는 경우가 많습니다.
어떤 정보를 획득할수 있는지 알아 봤으니 구현할 내용에 대해 시나리오를 먼저 작성하겠습니다.
#안드로이드 카카오톡 소셜 로그인 연동 기능의 시나리오
1.유저가 카카오톡 로그인 버튼을 클릭하면
2.카카오톡 로그인을 통해 카카오 서버에 회원정보를 내려 받습니다.
#카카오톡 로그인 연동 준비
1.https://developers.kakao.com/ 으로 이동
2.앱 개발 시작하기 버튼 클릭
3.왼쪽 상단 앱 만들기 클릭
4.앱정보에 키확인
네이티브 키를 메모장에 복사해 두세요.
5. 아래 함수를 이용해서 앱의 해시 키값을 얻어냅니다. 해당 하는 해시키 값도 메모장에 복사해 둡니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public
static
final
String getKeyHash(Context context) {
try {
PackageInfo info
= context.getPackageManager().getPackageInfo(context.getPackageName(),
PackageManager.GET_SIGNATURES);
for (Signature signature : info.signatures) {
MessageDigest md
= MessageDigest.getInstance(
"SHA");
md.update(signature.toByteArray());
String keyHash
= Base64.encodeToString(md.digest(), Base64.DEFAULT);
Log.d(TAG
+
"KeyHash:%s", keyHash);
return keyHash;
}
}
catch (NameNotFoundException e) {
Log.d(TAG
+
"getKeyHash Error:%s", e.getMessage());
}
catch (NoSuchAlgorithmException e) {
Log.d(TAG
+
"getKeyHash Error:%s", e.getMessage());
}
return
"";
}
|
cs |
6. 카카오톡 안드로이드 플랫폼 설정
앱 정보 옆에 설정을 클릭합니다.
7. 자신이 생성한 패키지명을 입력하고 Android를 선택한 후 추가 버튼을 클릭합니다.
7. 5에서 생성한 해시키를 키 해시에 입력합니다. 그리고 네이티브 앱키를 복사합니다.
#카카오톡 로그인 연동 구현
@AndroidManifest.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
<
?xml
version=
"1.0"
encoding=
"utf-8"
?>
xmlns:tools=
"http://schemas.android.com/tools"
package=
"mobileflow.co.kr"
>
<
uses-permission
android:name=
"android.permission.INTERNET"
/>
<
uses-permission
android:name=
"android.permission.ACCESS_WIFI_STATE"
/>
<
uses-permission
android:name=
"android.permission.ACCESS_NETWORK_STATE"
/>
<
application
android:allowBackup=
"true"
android:name=
".application.ApplicationUtil"
android:configChanges=
"keyboardHidden|orientation"
android:screenOrientation=
"portrait"
android:largeHeap=
"true"
android:debuggable=
"true"
android:icon=
"@mipmap/ic_launcher"
android:label=
"@string/app_name"
android:supportsRtl=
"true"
android:launchMode=
"singleInstance"
android:theme=
"@style/Mobileflow.Base"
tools:ignore=
"HardcodedDebugMode"
>
<
activity
android:name=
".activity.LoginActivity"
android:label=
"@string/app_name"
android:theme=
"@style/Theme.AppCompat.Light.NoActionBar"
>
<
intent-filter>
<
action
android:name=
"android.intent.action.MAIN"
/>
<
category
android:name=
"android.intent.category.LAUNCHER"
/>
</
intent-filter>
</
activity>
<!-- [kakaologin][start] 카카오 로그인 연동 -->
<
meta-data
android:name=
"com.kakao.sdk.AppKey"
android:value=
"7에서 복사한 네이티브 키 복사"
/>
<!-- [kakaologin][end] -->
</
application>
</
manifest>
|
cs |
35-37 행에 메모해둔 네이티브 키를 복사 합니다.
@ KakaoSDKAdapter.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
|
public
class KakaoSDKAdapter
extends KakaoAdapter {
public Activity mActivity;
public KakaoSDKAdapter(Activity activity){
this.mActivity
= activity;
}
/**
* 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 ApprovalType getApprovalType() {
return ApprovalType.INDIVIDUAL;
}
@Override
public
boolean isSaveFormData() {
return
true;
}
};
}
@Override
public IApplicationConfig getApplicationConfig() {
return
new IApplicationConfig() {
@Override
public Activity getTopActivity() {
return mActivity;
}
@Override
public Context getApplicationContext() {
return mActivity.getApplicationContext();
}
};
}
}
|
cs |
카카오톡 어댑터를 구현합니다.
이제 카카오톡 로그인을 구현할 준비가 되었으니 카카오톡 로그인을 실행할 UI를 만듭니다.
@ activity_login.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
<
RelativeLayout
xmlns:android=
"http://schemas.android.com/apk/res/android"
xmlns:tools=
"http://schemas.android.com/tools"
tools:ignore=
"MissingPrefix"
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:background=
"@color/key_color_white"
android:id=
"@+id/wrapper"
>
<!-- 로그인 -->
<!-- 전체 / 간격 -->
<
LinearLayout
android:layout_width=
"match_parent"
android:layout_height=
"match_parent"
android:orientation=
"vertical"
android:paddingLeft=
"@dimen/dimen_45dp"
android:paddingRight=
"@dimen/dimen_45dp"
android:background=
"@color/key_color_dark"
>
<!-- # 상단 앱 이미지, 글 -->
<
LinearLayout
android:id=
"@+id/wrapper_top"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
android:gravity=
"center"
android:layout_marginTop=
"65dp"
>
<!-- 이미지 시작 -->
<
LinearLayout
android:id=
"@+id/box_img_app_icon"
android:layout_width=
"wrap_content"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
android:gravity=
"center"
>
<
ImageView
android:id=
"@+id/img_app_icon"
android:layout_width=
"100dp"
android:layout_height=
"100dp"
android:background=
"@mipmap/ic_launcher"
android:gravity=
"center"
/>
<!-- 이미지 -->
</
LinearLayout>
<!-- 이미지 끝 -->
<!-- 텍스트 -->
<
LinearLayout
android:id=
"@+id/box_txt_ggagga"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"horizontal"
android:gravity=
"center"
android:layout_marginTop=
"15dp"
>
</
LinearLayout>
<!-- 텍스트 끝-->
</
LinearLayout>
<!-- # 상단 앱 이미지, 글 -->
<
LinearLayout
android:id=
"@+id/box_btn_logins"
android:layout_width=
"match_parent"
android:layout_height=
"wrap_content"
android:orientation=
"vertical"
android:layout_marginTop=
"10dp"
android:layout_marginBottom=
"@dimen/btn_margin_bottom"
>
<!--카카오 로그인 버튼 -->
<
Button
android:id=
"@+id/btn_login_kakao"
android:layout_width=
"match_parent"
android:layout_height=
"@dimen/btn_height"
android:background=
"@drawable/style_btn_yellow_kakao"
android:gravity=
"center"
android:text=
"@string/login_kakao"
android:textSize=
"@dimen/font_large"
android:textColor=
"@color/key_color_black"
android:textStyle=
"bold"
fontPath=
"fonts/barun_gothic_bold.ttf.mp3"
/>
</
LinearLayout>
<!-- 카카오 로그인 버튼 -->
</
LinearLayout>
</
LinearLayout>
</
RelativeLayout>
|
cs |
이제 UI도 생성해 두었으니 실행할 내용을 코드로 옮깁니다.
@ LoginActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
|
public
class LoginActivity
extends BaseActivity
implements View.OnClickListener {
private KakaoSessionCallback mKakaoCallback;
///Kakao Login
private Button mBtnLoginKakao;
@Override
protected
void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
mBtnLoginKakao
= (Button) findViewById(R.id.btn_login_kakao);
mBtnLoginKakao.setOnClickListener(
this);
initKakao();
}
@Override
protected
void onDestroy() {
super.onDestroy();
Session.getCurrentSession().removeCallback(mKakaoCallback);
}
@Override
public
void onClick(View v) {
switch (v.getId()) {
case R.id.btn_login_kakao:
//카카오 로그인 버튼
com.kakao.auth.Session.getCurrentSession().open(AuthType.KAKAO_TALK_EXCLUDE_NATIVE_LOGIN, mActivity);
break;
//카카오 로그인 버튼
}
}
/****************************************************************************************************************
* Kakao
****************************************************************************************************************/
private
void initKakao(){
KakaoSDK.init(
new KakaoSDKAdapter(mActivity));
mKakaoCallback
=
new KakaoSessionCallback(mActivity,
this);
com.kakao.auth.Session.getCurrentSession().addCallback(mKakaoCallback);
com.kakao.auth.Session.getCurrentSession().checkAndImplicitOpen();
}
public
void KakaoRequestMe() {
UserManagement.requestMe(
new MeResponseCallback() {
@Override
public
void onFailure(ErrorResult errorResult) {
int ErrorCode
= errorResult.getErrorCode();
int ClientErrorCode
=
-
777;
if (ErrorCode
=
= ClientErrorCode) {
Log.d(TAG,
"카카오톡 서버의 네트워크가 불안정합니다. 잠시 후 다시 시도해주세요.");
}
else {
Log.d(TAG,
"알 수 없는 오류로 카카오로그인 실패 ");
}
}
@Override
public
void onSessionClosed(ErrorResult errorResult) {
Log.d(TAG,
"세션 종료");
}
@Override
public
void onSuccess(UserProfile userProfile) {
// 로그인 성공시 사용자정보 추출(완료)
Log.d(TAG,
String.
valueOf(userProfile));
Log.d(TAG,
String.
valueOf(userProfile.getId()));
}
@Override
public
void onNotSignedUp() {
// 자동가입이 아닐경우 동의창
}
});
}
/****************************************************************************************************************
* Kakao
****************************************************************************************************************/
}
|
cs |
로그인 페이지도 기능을 구현합니다.
@ KakaoSessionCallBack.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
public
class KakaoSessionCallback
implements ISessionCallback {
public Activity mActivity;
public PrefUtil mPrefUtil;
public LoginActivity mLoginActivity;
public KakaoSessionCallback(Activity activity, LoginActivity loginActivity){
this.mActivity
= activity;
mPrefUtil
=
new PrefUtil(mActivity);
this.mLoginActivity
= loginActivity;
}
@Override
public
void onSessionOpened() {
Log.d(
"TAG",
"세션 오픈");
// 세션 연결성공 시 redirectSignupActivity() 호출
mLoginActivity.KakaoRequestMe();
}
@Override
public
void onSessionOpenFailed(KakaoException exception) {
if(exception
!
=
null) {
Log.d(
"TAG" , exception.getMessage());
}
}
}
|
cs |
로그인 성공시 구현할 부분을 정의해 둡니다.
#카카오톡 로그인 테스트.
* 첫번째 화면에 카카오톡 로그인 버튼을 클릭하면 아래와 같은 화면이 나옵니다.
* 제 계정을 입력해보았습니다.
* 이제 사용자 정보 사용 동의를 확인 합니다.
#유저쪽에는 카카오톡으로 부터 유저에게 톡이 전송됩니다.
KakaoRequestMe의 onSuccess 내에서 필요한 부분을 마저 구현하시면 됩니다.