Skip to content

Commit

Permalink
#9 [Feat] : 추가 TokenInterceptor에 토큰 및 SharedPreference의 토큰
Browse files Browse the repository at this point in the history
  • Loading branch information
imtaejugkim committed Nov 15, 2024
1 parent 0b4122c commit 7c6898b
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 29 deletions.
7 changes: 6 additions & 1 deletion app/src/main/java/org/sopt/and/Application.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import org.sopt.and.domain.SharedPreferenceManager
class Application : Application() {
override fun onCreate() {
super.onCreate()
SharedPreferenceManager.initialize(this)
appContext = this
}

companion object {
lateinit var appContext: Application
private set
}
}
8 changes: 5 additions & 3 deletions app/src/main/java/org/sopt/and/data/ApiFactory.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,11 @@ object ApiFactory {
level = HttpLoggingInterceptor.Level.BODY
}

private val client = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.build()
private val client = OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.addInterceptor(TokenInterceptor())
.build()


val retrofit: Retrofit by lazy {
Retrofit.Builder()
Expand Down
18 changes: 18 additions & 0 deletions app/src/main/java/org/sopt/and/data/TokenInterceptor.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.sopt.and.data

import okhttp3.Interceptor
import okhttp3.Response
import org.sopt.and.domain.SharedPreferenceManager

class TokenInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
val token = SharedPreferenceManager.getAccessToken()
val requestBuilder = chain.request().newBuilder()

if (token != null) {
requestBuilder.addHeader("token", token)
}

return chain.proceed(requestBuilder.build())
}
}
27 changes: 27 additions & 0 deletions app/src/main/java/org/sopt/and/data/dto/UserLoginDto.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.sopt.and.data.dto

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class RequestUserLoginDto(
@SerialName("username")
val username: String,
@SerialName("password")
val password: String,
)

@Serializable
data class ResponseUserLoginDto(
// success와 failed의 다른 필드를 정의하기 위해 null로 설정
@SerialName("result")
val result: ResponseLoginResultDto? = null,
@SerialName("code")
val code: String? = null
)

@Serializable
data class ResponseLoginResultDto(
@SerialName("token")
val token: String
)
7 changes: 7 additions & 0 deletions app/src/main/java/org/sopt/and/data/service/UserService.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package org.sopt.and.data.service

import org.sopt.and.data.dto.RequestUserLoginDto
import org.sopt.and.data.dto.RequestUserRegisterDto
import org.sopt.and.data.dto.ResponseUserLoginDto
import org.sopt.and.data.dto.ResponseUserRegisterDto
import retrofit2.Call
import retrofit2.http.Body
Expand All @@ -11,4 +13,9 @@ interface UserService {
fun postUserRegister(
@Body request: RequestUserRegisterDto
): Call<ResponseUserRegisterDto>

@POST("/login")
fun postUserLogin(
@Body request: RequestUserLoginDto
): Call<ResponseUserLoginDto>
}
23 changes: 10 additions & 13 deletions app/src/main/java/org/sopt/and/domain/SharedPreferenceManager.kt
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
package org.sopt.and.domain

import android.content.Context
import android.content.SharedPreferences
import org.sopt.and.Application

object SharedPreferenceManager {
private lateinit var sharedPreferences: SharedPreferences
private const val PREF_NAME = "app_preferences"
private val preferences = Application.appContext.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE)

fun initialize(context: Context) {
// 이미 초기화된 경우에는 초기화를 건너뛰게 설정
if(::sharedPreferences.isInitialized){
return
}
sharedPreferences = context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE)
fun saveToken(token: String) {
preferences.edit().putString("token", token).apply()
}

fun saveUserId(userId: String) {
sharedPreferences.edit().putString("user_id", userId).apply()
fun saveId(userId: String) {
preferences.edit().putString("userId", userId).apply()
}

fun getUserId(): String? {
return sharedPreferences.getString("user_id", null)
fun getAccessToken(): String? {
return preferences.getString("token", null)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ fun MyScreen(paddingValues: PaddingValues) {
)
Spacer(modifier = Modifier.size(8.dp))
Text(
text = "${SharedPreferenceManager.getUserId()}",
text = "${SharedPreferenceManager.getAccessToken()}",
style = Typography.titleSmall,
color = Color.White,
)
Expand Down
41 changes: 30 additions & 11 deletions app/src/main/java/org/sopt/and/presentation/signup/UserViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,16 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import org.sopt.and.R
import org.sopt.and.data.ServicePool
import org.sopt.and.data.dto.RequestUserLoginDto
import org.sopt.and.data.dto.RequestUserRegisterDto
import org.sopt.and.data.dto.ResponseUserLoginDto
import org.sopt.and.data.dto.ResponseUserRegisterDto
import org.sopt.and.domain.SharedPreferenceManager
import org.sopt.and.domain.SharedPreferenceManager.saveToken
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlin.math.log

interface AuthState {
class Success(val type: AuthType) : AuthState
Expand All @@ -38,8 +42,8 @@ class UserViewModel : ViewModel() {
val authState: StateFlow<AuthState?> = _authState.asStateFlow()

// 유저 정보를 관리
private val _userState = mutableStateOf<ResponseUserRegisterDto?>(null)
val userState: State<ResponseUserRegisterDto?> get() = _userState
private val _userState = mutableStateOf<ResponseUserLoginDto?>(null)
val userState: State<ResponseUserLoginDto?> get() = _userState


// 회원가입 로직
Expand All @@ -62,10 +66,7 @@ class UserViewModel : ViewModel() {
Callback<ResponseUserRegisterDto>{
override fun onResponse(call: Call<ResponseUserRegisterDto>, response: Response<ResponseUserRegisterDto>) {
if (response.isSuccessful) {
_userState.value = response.body()
_authState.value = AuthState.Success(AuthType.SIGNUP)
userData = UserData(request.username, request.password, request.hobby)

} else {
val error = response.message()
Log.e("error", error.toString())
Expand All @@ -82,12 +83,30 @@ class UserViewModel : ViewModel() {
// 로그인 로직
fun logIn(id: String, password: String) {
viewModelScope.launch {
if (id == userData.userId && password == userData.userPassword) {
_authState.value = AuthState.Success(AuthType.LOGIN)
SharedPreferenceManager.saveUserId(userData.userId)
} else {
_authState.value = AuthState.Error(R.string.log_in_error, AuthType.LOGIN)
}
userService.postUserLogin(RequestUserLoginDto(id, password)).enqueue(object :
Callback<ResponseUserLoginDto>{
override fun onResponse(call: Call<ResponseUserLoginDto>, response: Response<ResponseUserLoginDto>) {
if(response.isSuccessful) {
val loginResponse = response.body()
_userState.value = loginResponse
loginResponse?.result?.token?.let {
// SharedPreference에 토큰 저장
saveToken(it)
}

Log.d("token?", _userState.value.toString())
_authState.value = AuthState.Success(AuthType.LOGIN)
} else {
val error = response.message()
Log.e("error", error.toString())
}
}

override fun onFailure(call: Call<ResponseUserLoginDto>, t: Throwable) {
Log.e("failure", t.message.toString())
}

})
}
}
}

0 comments on commit 7c6898b

Please sign in to comment.