Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/#26 feat sns login #30

Open
wants to merge 31 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d6cbb56
#26 [fix] Fix retrofit error
imseongwoo Nov 21, 2022
e23cb0f
#26 [add] Add matchNaverAccount func in RegexUtil.kt
imseongwoo Dec 29, 2022
f5ecedc
#26 [add] Add kakao login
imseongwoo Dec 29, 2022
50121cf
#26 [add] Add naver login
imseongwoo Dec 29, 2022
ab3d673
#26 [add] Add social auto login
imseongwoo Dec 30, 2022
3f71536
#26 [chore] Extract string
imseongwoo Dec 30, 2022
09a63a5
#26 [chore] Delete unuse library
imseongwoo Dec 30, 2022
2992479
#26 [mod] Modify code convention
imseongwoo Dec 30, 2022
58bb6b6
#26 [add] Add getCustomKakaoSignUpEmail function
imseongwoo Jan 2, 2023
01f45e2
#26 [chore] Delete unuse string value
imseongwoo Jan 2, 2023
5fc3dcd
Merge branch 'develop' of https://github.com/BCSDLab/JJBAKSA-ANDROID …
imseongwoo Jan 6, 2023
713500f
#26 [chore] Move business logic to viewmodel
imseongwoo Jan 6, 2023
6e85a9f
#26 [chore] Move naver login business logic to viewmodel and remove u…
imseongwoo Jan 6, 2023
5b3b164
#26 [chore] Delete unused signup function and unused import
imseongwoo Jan 6, 2023
85f532e
#26 [chore] Refactoring login business logic
imseongwoo Jan 7, 2023
d9cc432
#26 [chore] Delete unuse import
imseongwoo Jan 7, 2023
9cd1f7f
#26 [chore] Delete unuse file
imseongwoo Jan 7, 2023
163ce27
#26 [chore] Modify social login code
imseongwoo Jan 7, 2023
e70d4ac
#26 [chore] Modify indentation
imseongwoo Jan 7, 2023
e3bbfb4
#26 [chore] Modify indentation
imseongwoo Jan 7, 2023
2a69c96
#26 [chore] Modify socialLogin function variable to meaningful
imseongwoo Jan 9, 2023
7fafaca
#26 [add] Add email authenticate
imseongwoo Jan 9, 2023
36a82cd
#26 [mod] Modify custom kakao email to user's kakao email
imseongwoo Jan 10, 2023
fb3ec36
#26 [chore] Delete wildcard import
imseongwoo Jan 10, 2023
960849f
#26 [add] Add onBackPressed() function
imseongwoo Jan 10, 2023
b260358
#26 [add] Add Event class
imseongwoo Jan 14, 2023
e6b6548
#26 [add] Add scalar convert factory
imseongwoo Jan 14, 2023
599781e
#26 [add] Add kakao login
imseongwoo Jan 14, 2023
c644f85
#26 [chore] mod code convention
imseongwoo Jan 14, 2023
42d79cd
#26 [chore] remove comment
imseongwoo Jan 14, 2023
cd02886
#26 [chore] Add new line in SocialLoginUrlMapper.kt
imseongwoo Jan 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ android {
buildConfigField("String", "naver_client_id", getPropertyKey("naver_client_id"))
buildConfigField("String", "naver_client_secret", getPropertyKey("naver_client_secret"))
buildConfigField("String", "naver_client_name", getPropertyKey("naver_client_name"))
buildConfigField("String", "social_login_password", getPropertyKey("social_login_password"))
resValue("string", "kakao_oauth_host", getPropertyKey("kakao_oauth_host"))
}

Expand Down
6 changes: 4 additions & 2 deletions app/src/main/java/com/jjbaksa/jjbaksa/di/NetworkModule.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.jjbaksa.jjbaksa.di

import android.content.Context
import androidx.datastore.preferences.core.stringPreferencesKey
import com.google.gson.GsonBuilder
import com.jjbaksa.data.BASE_URL
import com.jjbaksa.data.api.AuthApi
import com.jjbaksa.data.api.NoAuthApi
Expand Down Expand Up @@ -35,6 +36,7 @@ annotation class NOAUTH
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
private val gson = GsonBuilder().setLenient().create()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

해당 객체가 필요한 이유가 혹시 있나요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use JsonReader.setLenient(true) to accept malformed JSON 이라는 에러가 발생해서 gson 객체 설정 후 retrofit 객체에 추가하였습니다.

private val httpLoggingInterceptor = HttpLoggingInterceptor().apply {
level = if (JjbaksaApp.instance.isDebug) {
HttpLoggingInterceptor.Level.BODY
Expand Down Expand Up @@ -133,7 +135,7 @@ fun provideRefreshInterceptor(): Interceptor {
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}

Expand All @@ -144,7 +146,7 @@ fun provideRefreshInterceptor(): Interceptor {
return Retrofit.Builder()
.client(okHttpClient)
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
}

Expand Down
123 changes: 48 additions & 75 deletions app/src/main/java/com/jjbaksa/jjbaksa/ui/social/SocialLoginActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ package com.jjbaksa.jjbaksa.ui.social

import android.content.Intent
import android.util.Log
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
import com.google.firebase.auth.FirebaseAuth
import com.jjbaksa.jjbaksa.BuildConfig
import androidx.activity.result.ActivityResultCallback
import androidx.activity.viewModels
import com.google.android.gms.auth.api.signin.GoogleSignIn
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
import com.google.android.gms.common.api.ApiException
Expand All @@ -17,108 +19,66 @@ import com.google.firebase.auth.GoogleAuthProvider
import com.jjbaksa.jjbaksa.R
import com.jjbaksa.jjbaksa.base.BaseActivity
import com.jjbaksa.jjbaksa.databinding.ActivitySocialLoginBinding
import com.kakao.sdk.auth.model.OAuthToken
import com.kakao.sdk.common.model.ClientError
import com.kakao.sdk.common.model.ClientErrorCause
import com.jjbaksa.jjbaksa.ui.mainpage.MainPageActivity
import com.kakao.sdk.user.UserApiClient
import com.navercorp.nid.NaverIdLoginSDK
import com.navercorp.nid.oauth.NidOAuthBehavior
import com.navercorp.nid.oauth.OAuthLoginCallback
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class SocialLoginActivity : BaseActivity<ActivitySocialLoginBinding>() {
private lateinit var activityResultLauncher: ActivityResultLauncher<Intent>
private lateinit var firebaseAuth: FirebaseAuth
private var userEmail: String = ""
private var tokenId: String? = null

companion object {
const val TAG = "SocialLogin"
}
private var googleUserEmail: String = ""
private var googleAccount: String = ""
private var googleTokenId: String? = ""
val viewModel: SocialLoginViewModel by viewModels()

override val layoutId: Int
get() = R.layout.activity_social_login

override fun initView() {
initNaverLogin()
initGoogleLogin()
initNaverLogin()
viewModel.getAutoLoginFlag()
}

override fun subscribe() {
viewModel.loginState.observe(this@SocialLoginActivity) {
if (it != null) {
if (it.isSuccess) {
goToMainActivity()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

로그인 성공한 이후 뒤로가기하면 다시 로그인 화면이 나와서는 안됩니다. 뒤로가기시 로그인 화면이 나오지 않도록 처리해주세요

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

960849f 에서 수정했습니다.

} else {
if (it.erroMessage.isNotEmpty()) {
showToast(it.erroMessage)
}
}
}
}
}

override fun initEvent() {
with(binding) {
buttonKakaoLogin.setOnClickListener {
wnehdals marked this conversation as resolved.
Show resolved Hide resolved
UserApiClient.instance.accessTokenInfo { tokenInfo, error ->
if (error != null) {
Log.d(TAG, "토큰 정보 보기 실패", error)
} else if (tokenInfo != null) {
Log.d(TAG, "토큰 정보 보기 성공", error)
}
}

val callback: (OAuthToken?, Throwable?) -> Unit = { token, error ->
wnehdals marked this conversation as resolved.
Show resolved Hide resolved
if (error != null) {
Log.e(TAG, "카카오계정으로 로그인 실패", error)
imseongwoo marked this conversation as resolved.
Show resolved Hide resolved
} else if (token != null) {
Log.e(TAG, "카카오계정으로 로그인 성공 ${token.accessToken}")
}
}

if (UserApiClient.instance.isKakaoTalkLoginAvailable(this@SocialLoginActivity)) {
UserApiClient.instance.loginWithKakaoTalk(this@SocialLoginActivity) { token, error ->
if (error != null) {
Log.e(TAG, "카카오톡으로 로그인 실패", error)
if (error is ClientError && error.reason == ClientErrorCause.Cancelled) {
return@loginWithKakaoTalk
}
UserApiClient.instance.loginWithKakaoAccount(
this@SocialLoginActivity,
callback = callback
)
} else if (token != null) {
Log.i(TAG, "카카오톡으로 로그인 성공 ${token.accessToken}")
}
}
UserApiClient.instance.loginWithKakaoTalk(this@SocialLoginActivity, callback = viewModel.kakaoLoginCallback)
} else {
UserApiClient.instance.loginWithKakaoAccount(
this@SocialLoginActivity,
callback = callback
)
UserApiClient.instance.loginWithKakaoAccount(this@SocialLoginActivity, callback = viewModel.kakaoLoginCallback)
}
}
buttonNaverLogin.setOnClickListener {
NaverIdLoginSDK.behavior = NidOAuthBehavior.DEFAULT
NaverIdLoginSDK.authenticate(
this@SocialLoginActivity,
object : OAuthLoginCallback {
override fun onSuccess() {
Log.d(TAG, "onSuccess")
}

override fun onFailure(httpStatus: Int, message: String) {
val errorCode = NaverIdLoginSDK.getLastErrorCode().code
val errorDescription = NaverIdLoginSDK.getLastErrorDescription()
Log.d(TAG, "authenticate onFailure()")
Log.d(TAG, "errorCode : $errorCode / errorDesc : $errorDescription")
}

override fun onError(errorCode: Int, message: String) {
onFailure(errorCode, message)
}
}
)
NaverIdLoginSDK.authenticate(this@SocialLoginActivity, viewModel.oAuthLoginCallback)
}

buttonGoogleLogin.setOnClickListener {
val googleSignInOptions =
GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestIdToken(getString(R.string.default_web_client_id))
.requestEmail()
.build()

val googleSignInClient =
GoogleSignIn.getClient(this@SocialLoginActivity, googleSignInOptions)

val signInIntent: Intent = googleSignInClient.signInIntent
activityResultLauncher.launch(signInIntent)
}
Expand Down Expand Up @@ -147,10 +107,9 @@ class SocialLoginActivity : BaseActivity<ActivitySocialLoginBinding>() {
if (activityResult.resultCode == RESULT_OK) {
val task = GoogleSignIn.getSignedInAccountFromIntent(activityResult.data)
task.getResult(ApiException::class.java)?.let { account ->
tokenId = account.idToken
Log.d(TAG, tokenId.toString())
if (tokenId != null && tokenId != "") {
Log.d(TAG, tokenId.toString())
googleTokenId = account.idToken
if (googleTokenId != null && googleTokenId != "") {
Log.d(TAG, googleTokenId.toString())
val authCredential: AuthCredential =
GoogleAuthProvider.getCredential(account.idToken, null)
firebaseAuthWithGoogle(authCredential, account)
Expand All @@ -167,14 +126,28 @@ class SocialLoginActivity : BaseActivity<ActivitySocialLoginBinding>() {
) {
firebaseAuth = FirebaseAuth.getInstance()
firebaseAuth.signInWithCredential(authCredential)
.addOnCompleteListener {
if (firebaseAuth.currentUser != null) {
.addOnCompleteListener(this) {
if (it.isSuccessful) {
val firebaseUser: FirebaseUser = firebaseAuth.currentUser!!
userEmail = firebaseUser.email.toString()
Log.d(TAG, tokenId.toString())
googleUserEmail = firebaseUser.email.toString()
showToast(firebaseUser.providerId)
Log.d(TAG, "providerId : ${firebaseUser.providerId}")
Log.d(TAG, googleTokenId.toString())
} else {
Log.d(TAG, "signInWithCredential failure")
showToast("signInWithCredential:failure")
}
}
}

private fun goToMainActivity() {
Intent(this, MainPageActivity::class.java).also { startActivity(it) }
}

fun showToast(msg: String) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show()
}

companion object {
const val TAG = "SocialLogin"
}
}
Loading