Skip to content

Commit

Permalink
feat: kakao 로그인 전략 추가 (#197)
Browse files Browse the repository at this point in the history
  • Loading branch information
easyhz committed Sep 30, 2024
1 parent 3c19800 commit 9ce3c03
Show file tree
Hide file tree
Showing 10 changed files with 130 additions and 3 deletions.
11 changes: 11 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@
android:scheme="https"/>
</intent-filter>
</activity>
<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" />

<data android:host="oauth"
android:scheme="@string/kakao_native_app_key" />
</intent-filter>
</activity>
</application>

</manifest>
7 changes: 7 additions & 0 deletions app/src/main/java/com/easyhz/noffice/NofficeApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import android.app.NotificationManager
import android.content.Context
import android.os.Build
import com.easyhz.noffice.data.notification.service.NotificationService
import com.kakao.sdk.common.KakaoSdk
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class NofficeApplication: Application() {
override fun onCreate() {
super.onCreate()
createNotificationChannel()
initKakao()
}

private fun createNotificationChannel() {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
Expand All @@ -26,4 +29,8 @@ class NofficeApplication: Application() {
notificationManager.createNotificationChannel(channel)
}
}

private fun initKakao() {
KakaoSdk.init(this, BuildConfig.KAKAO_NATIVE_APP_KEY)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,9 @@ val DimColor = Color(0xFF121212).copy(alpha = 0.5f)
@Stable
val Red100 = Color(0xFFFFF0EF)
@Stable
val Red = Color(0xFFFF3F3F)
val Red = Color(0xFFFF3F3F)

@Stable
val KakaoYellow = Color(0xFFFEE500)
@Stable
val KakaoBlack = Color(0xFF000000)
16 changes: 16 additions & 0 deletions core/design-system/src/main/res/drawable/ic_logo_kakao.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="19dp"
android:height="19dp"
android:viewportWidth="19"
android:viewportHeight="19">
<group>
<clip-path
android:pathData="M0.5,0.5h18v18h-18z"/>
<path
android:pathData="M9.5,1.443C4.79,1.443 0.5,5.229 0.5,8.432C0.5,10.832 2.058,12.949 4.431,14.207L3.433,17.873C3.344,18.198 3.713,18.456 3.996,18.269L8.373,15.364C8.742,15.4 9.118,15.421 9.5,15.421C14.47,15.421 18.5,12.292 18.5,8.432C18.5,5.229 14.47,1.443 9.5,1.443Z"
android:strokeAlpha="0.902"
android:fillColor="#000000"
android:fillType="evenOdd"
android:fillAlpha="0.902"/>
</group>
</vector>
3 changes: 2 additions & 1 deletion core/design-system/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<resources>
<string name="social_login_google">Google로 로그인</string>
<string name="social_login_google">Google로 시작하기</string>
<string name="social_login_kakao">Kakao로 시작하기</string>

<string name="home_date_empty">약속된 날짜가 없어요</string>
<string name="home_place_empty">약속된 장소가 없어요</string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package com.easyhz.noffice.data.auth.di.strategy

import com.easyhz.noffice.data.auth.strategy.BaseStrategy
import com.easyhz.noffice.data.auth.strategy.GoogleStrategy
import com.easyhz.noffice.data.auth.strategy.KakaoStrategy
import com.easyhz.noffice.data.auth.util.google
import com.easyhz.noffice.data.auth.util.kakao
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
Expand All @@ -18,4 +20,9 @@ object LoginStrategyModule {
@IntoMap
@StringKey(google)
fun provideGoogleStrategy(googleStrategy: GoogleStrategy): BaseStrategy = googleStrategy

@Provides
@IntoMap
@StringKey(kakao)
fun provideKakaoStrategy(kakaoStrategy: KakaoStrategy): BaseStrategy = kakaoStrategy
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.easyhz.noffice.data.auth.strategy

import android.content.Context
import android.util.Log
import com.kakao.sdk.auth.model.OAuthToken
import com.kakao.sdk.common.model.ClientError
import com.kakao.sdk.common.model.ClientErrorCause
import com.kakao.sdk.user.UserApiClient
import kotlinx.coroutines.suspendCancellableCoroutine
import javax.inject.Inject
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

class KakaoStrategy @Inject constructor() : BaseStrategy() {
private val tag = this.javaClass.name
override suspend fun login(context: Context): Result<String> = runCatching {
val token = loginWithKakaoTalk(context)
Log.d(tag, "카카오톡으로 로그인 성공 ${token.accessToken}")
token.accessToken
}.recoverCatching { error ->
Log.d(tag, "카카오톡으로 로그인 실패 : $error")

if (error is ClientError && error.reason == ClientErrorCause.Cancelled) throw error // 의도적인 로그인 취소

val token = loginWithKakaoAccount(context)
Log.d(tag, "카카오 계정으로 로그인 성공 ${token.accessToken}")
token.accessToken
}

override suspend fun logout(context: Context): Result<Unit> {
TODO("Not yet implemented")
}

/**
* 카카오톡으로 로그인
*
* @param context Context
* @return [OAuthToken] 로그인 성공 시 발급되는 토큰
*/
private suspend fun loginWithKakaoTalk(context: Context): OAuthToken = suspendCancellableCoroutine { continuation ->
UserApiClient.instance.loginWithKakaoTalk(context) { token, error ->
when {
error != null -> continuation.resumeWithException(error)
token != null -> continuation.resume(token)
else -> continuation.resumeWithException(IllegalStateException("Unexpected error during KakaoTalk login"))
}
}
}

/**
* 카카오 계정으로 로그인
*
* * 카카오톡에 연결된 카카오 계정이 없을 경우 카카오 계정 로그인 시도
*
* @param context Context
* @return [OAuthToken] 로그인 성공 시 발급되는 토큰
*/
private suspend fun loginWithKakaoAccount(context: Context): OAuthToken = suspendCancellableCoroutine { continuation ->
UserApiClient.instance.loginWithKakaoAccount(context) { token, error ->
when {
error != null -> continuation.resumeWithException(error)
token != null -> continuation.resume(token)
else -> continuation.resumeWithException(IllegalStateException("Unexpected error during KakaoAccount login"))
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package com.easyhz.noffice.data.auth.util
import com.easyhz.noffice.core.network.model.request.sign.LoginRequest

const val google = "GOOGLE"
const val kakao = "KAKAO"

enum class Provider(
val type: String
) {
GOOGLE(type = google);
GOOGLE(type = google),
KAKAO(type = kakao);

fun getLoginRequest(code: String) = LoginRequest(
code = code,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ internal fun LoginView(
socialLoginType = SocialLoginType.GOOGLE,
onClick = onClick
)
SocialLoginButton(
socialLoginType = SocialLoginType.KAKAO,
onClick = onClick
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import androidx.compose.ui.graphics.Color
import com.easyhz.noffice.core.design_system.R
import com.easyhz.noffice.core.design_system.theme.Grey50
import com.easyhz.noffice.core.design_system.theme.Grey800
import com.easyhz.noffice.core.design_system.theme.KakaoBlack
import com.easyhz.noffice.core.design_system.theme.KakaoYellow

enum class SocialLoginType(
@StringRes val stringId: Int,
Expand All @@ -18,5 +20,10 @@ enum class SocialLoginType(
iconId = R.drawable.ic_logo_google,
containerColor = Grey50,
contentColor = Grey800,
), KAKAO(
stringId = R.string.social_login_kakao,
iconId = R.drawable.ic_logo_kakao,
containerColor = KakaoYellow,
contentColor = KakaoBlack,
);
}

0 comments on commit 9ce3c03

Please sign in to comment.