-
Notifications
You must be signed in to change notification settings - Fork 1
DataStore 토큰 저장 기능 구현 #58
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /build |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| plugins { | ||
| alias(libs.plugins.twix.android.library) | ||
| alias(libs.plugins.twix.koin) | ||
| alias(libs.plugins.serialization) | ||
| } | ||
|
|
||
| android { | ||
| namespace = "com.twix.datastore" | ||
| } | ||
|
|
||
| dependencies { | ||
| implementation(projects.core.token) | ||
|
|
||
| implementation(libs.androidx.datastore) | ||
| implementation(libs.kotlinx.serialization.json) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Add project specific ProGuard rules here. | ||
| # You can control the set of applied configuration files using the | ||
| # proguardFiles setting in build.gradle. | ||
| # | ||
| # For more details, see | ||
| # http://developer.android.com/guide/developing/tools/proguard.html | ||
|
|
||
| # If your project uses WebView with JS, uncomment the following | ||
| # and specify the fully qualified class name to the JavaScript interface | ||
| # class: | ||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| # public *; | ||
| #} | ||
|
|
||
| # Uncomment this to preserve the line number information for | ||
| # debugging stack traces. | ||
| #-keepattributes SourceFile,LineNumberTable | ||
|
|
||
| # If you keep the line number information, uncomment this to | ||
| # hide the original source file name. | ||
| #-renamesourcefileattribute SourceFile |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| <?xml version="1.0" encoding="utf-8"?> | ||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"> | ||
|
|
||
| </manifest> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package com.twix.datastore | ||
|
|
||
| import androidx.datastore.core.Serializer | ||
| import kotlinx.coroutines.Dispatchers | ||
| import kotlinx.coroutines.withContext | ||
| import kotlinx.serialization.Serializable | ||
| import kotlinx.serialization.SerializationException | ||
| import kotlinx.serialization.json.Json | ||
| import java.io.InputStream | ||
| import java.io.OutputStream | ||
|
|
||
| @Serializable | ||
| internal data class AuthConfigure( | ||
| val accessToken: String = | ||
| "eyJhbGciOiJIUzM4NCJ9." + | ||
| "eyJzdWIiOiIxIiwidHlwZSI6ImFjY2VzcyIsImlhdCI6MTc3MDI0NzM0NCwiZXhwIjoxNzcwODUyMTQ0fQ." + | ||
| "67rDscm8BeayYFA1gfcEMliEdEh8-HTUyE5TwmAT8Ef8ZvtaWczxpMNZqI5htiek", | ||
| val refreshToken: String = | ||
| "eyJhbGciOiJIUzM4NCJ9." + | ||
| "eyJzdWIiOiIxIiwidHlwZSI6InJlZnJlc2giLCJpYXQiOjE3NzAyNDczNDQsImV4cCI6MTc3MDg1MjE0NH0." + | ||
| "zgUYdR6onyeY5EaH2_pWLs1rjNLf8m8ZeXsY7Cbk99a_2tzR0rDBZO_hdGTnorRL", | ||
| ) | ||
|
|
||
| internal object AuthConfigureSerializer : Serializer<AuthConfigure> { | ||
| override val defaultValue: AuthConfigure | ||
| get() = AuthConfigure() | ||
|
|
||
| override suspend fun readFrom(input: InputStream): AuthConfigure = | ||
| try { | ||
| Json.decodeFromString( | ||
| deserializer = AuthConfigure.serializer(), | ||
| string = input.readBytes().decodeToString(), | ||
| ) | ||
| } catch (e: SerializationException) { | ||
| defaultValue | ||
| } | ||
chanho0908 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| override suspend fun writeTo( | ||
| t: AuthConfigure, | ||
| output: OutputStream, | ||
| ) { | ||
| withContext(Dispatchers.IO) { | ||
| output.write( | ||
| Json | ||
| .encodeToString( | ||
| serializer = AuthConfigure.serializer(), | ||
| value = t, | ||
| ).encodeToByteArray(), | ||
| ) | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| package com.twix.datastore | ||
|
|
||
| import android.content.Context | ||
| import androidx.datastore.core.DataStore | ||
| import com.twix.token.TokenProvider | ||
| import kotlinx.coroutines.flow.first | ||
|
|
||
| class AuthTokenProvider( | ||
| private val context: Context, | ||
| ) : TokenProvider { | ||
| private val dataStore: DataStore<AuthConfigure> | ||
| get() = context.authDataStore | ||
|
|
||
| override suspend fun accessToken(): String = dataStore.data.first().accessToken | ||
|
|
||
| override suspend fun refreshToken(): String = dataStore.data.first().refreshToken | ||
|
|
||
| override suspend fun saveToken( | ||
| accessToken: String, | ||
| refreshToken: String, | ||
| ) { | ||
| dataStore.updateData { | ||
| it.copy(accessToken = accessToken, refreshToken = refreshToken) | ||
| } | ||
| } | ||
|
|
||
| override suspend fun clear() { | ||
| dataStore.updateData { | ||
| it.copy(accessToken = "", refreshToken = "") | ||
| } | ||
|
Comment on lines
+11
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: fd -t f -e kt | head -20Repository: YAPP-Github/Twix-Android Length of output: 1630 🏁 Script executed: rg "authDataStore" --type kt -A 3 -B 3Repository: YAPP-Github/Twix-Android Length of output: 94 🏁 Script executed: rg "context\.authDataStore\|authDataStore\s*=" --type kt -A 5Repository: YAPP-Github/Twix-Android Length of output: 94 🏁 Script executed: find . -type f -name "*.kt" | xargs grep -l "DataStore\|authDataStore" | head -10Repository: YAPP-Github/Twix-Android Length of output: 201 🏁 Script executed: cat -n core/datastore/src/main/java/com/twix/datastore/DataStore.ktRepository: YAPP-Github/Twix-Android Length of output: 431 🏁 Script executed: cat -n core/datastore/src/main/java/com/twix/datastore/AuthTokenProvider.ktRepository: YAPP-Github/Twix-Android Length of output: 1175 🏁 Script executed: find . -type f -name "*Serializer*" | grep -i authRepository: YAPP-Github/Twix-Android Length of output: 50 🏁 Script executed: rg "Serializer|serializer" --type-listRepository: YAPP-Github/Twix-Android Length of output: 457 🏁 Script executed: find . -type f \( -name "*.kt" -o -name "*.java" \) | xargs grep -l "AuthConfigureSerializer" | head -5Repository: YAPP-Github/Twix-Android Length of output: 197 🏁 Script executed: rg "object AuthConfigureSerializer|class AuthConfigureSerializer" -A 20Repository: YAPP-Github/Twix-Android Length of output: 2099 🏁 Script executed: find . -type f -name "*.kt" | xargs grep -l "Serializer" | grep -i authRepository: YAPP-Github/Twix-Android Length of output: 134 🏁 Script executed: cat -n core/datastore/src/main/java/com/twix/datastore/AuthConfigure.ktRepository: YAPP-Github/Twix-Android Length of output: 2187 토큰이 평문으로 저장되어 보안 위험이 있습니다. AuthConfigureSerializer의 readFrom/writeTo에서 Json.decodeFromString/encodeToString를 사용하고 있어, 토큰이 보호 없이 "auth-configure.json" 파일에 평문으로 저장됩니다. 루팅된 기기나 백업 환경에서 토큰이 노출될 수 있습니다. 개선 방안:
EncryptedDataStore 적용이 어렵다면, Serializer에 암호화 로직을 추가하는 예시를 제공할 수 있습니다. 보안 요구사항상 암호화 적용이 필수인지 확인 부탁드립니다. 🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.twix.datastore | ||
|
|
||
| import android.content.Context | ||
| import androidx.datastore.core.DataStore | ||
| import androidx.datastore.dataStore | ||
|
|
||
| internal val Context.authDataStore: DataStore<AuthConfigure> by dataStore( | ||
| fileName = "auth-configure.json", | ||
| serializer = AuthConfigureSerializer, | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| package com.twix.datastore.di | ||
|
|
||
| import com.twix.datastore.AuthTokenProvider | ||
| import com.twix.token.TokenProvider | ||
| import org.koin.dsl.module | ||
|
|
||
| val dataStoreModule = | ||
| module { | ||
| single<TokenProvider> { AuthTokenProvider(get()) } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| /build |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| plugins { | ||
| alias(libs.plugins.twix.java.library) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| # Add project specific ProGuard rules here. | ||
| # You can control the set of applied configuration files using the | ||
| # proguardFiles setting in build.gradle. | ||
| # | ||
| # For more details, see | ||
| # http://developer.android.com/guide/developing/tools/proguard.html | ||
|
|
||
| # If your project uses WebView with JS, uncomment the following | ||
| # and specify the fully qualified class name to the JavaScript interface | ||
| # class: | ||
| #-keepclassmembers class fqcn.of.javascript.interface.for.webview { | ||
| # public *; | ||
| #} | ||
|
|
||
| # Uncomment this to preserve the line number information for | ||
| # debugging stack traces. | ||
| #-keepattributes SourceFile,LineNumberTable | ||
|
|
||
| # If you keep the line number information, uncomment this to | ||
| # hide the original source file name. | ||
| #-renamesourcefileattribute SourceFile |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| package com.twix.token | ||
|
|
||
| interface TokenProvider { | ||
| suspend fun accessToken(): String | ||
|
|
||
| suspend fun refreshToken(): String | ||
|
|
||
| suspend fun saveToken( | ||
| accessToken: String, | ||
| refreshToken: String, | ||
| ) | ||
|
|
||
| suspend fun clear() | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,7 @@ kotlinx-serialization-json = "1.9.0" | |
| # AndroidX | ||
| androidx-core-ktx = "1.17.0" | ||
| androidx-lifecycle-runtime-ktx = "2.10.0" | ||
| androidx-datastore = "1.2.0" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Find gradle configuration files
git ls-files | grep -E "\.toml$|build\.gradle|settings\.gradle"Repository: YAPP-Github/Twix-Android Length of output: 646 🏁 Script executed: # Check the actual artifact configuration in libs.versions.toml
cat gradle/libs.versions.tomlRepository: YAPP-Github/Twix-Android Length of output: 9311 🏁 Script executed: # Search for DataStore imports to understand which library is being used
rg "import.*datastore" --type kotlin -iRepository: YAPP-Github/Twix-Android Length of output: 597 🏁 Script executed: # Look for DataStore API usage
rg "dataStore|DataStore|Preferences\|DataStoreFactory" --type kotlin -B 2 -A 3Repository: YAPP-Github/Twix-Android Length of output: 4271 🏁 Script executed: cat core/datastore/build.gradle.ktsRepository: YAPP-Github/Twix-Android Length of output: 401 🏁 Script executed: # Check the full AuthConfigure and AuthConfigureSerializer implementation
cat core/datastore/src/main/java/com/twix/datastore/AuthConfigure.ktRepository: YAPP-Github/Twix-Android Length of output: 1823 🏁 Script executed: cat core/datastore/src/main/java/com/twix/datastore/DataStore.ktRepository: YAPP-Github/Twix-Android Length of output: 361 DataStore 의존성을 수정해야 합니다 현재
문제: 🔧 수정 사항-androidx-datastore = { module = "androidx.datastore:datastore-preferences", version.ref = "androidx-datastore" }
+androidx-datastore = { module = "androidx.datastore:datastore", version.ref = "androidx-datastore" }🤖 Prompt for AI Agents |
||
|
|
||
| material = "1.13.0" | ||
|
|
@@ -71,6 +72,7 @@ appcompat = "1.7.1" | |
| # AndroidX | ||
| androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidx-core-ktx" } | ||
| androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "androidx-lifecycle-runtime-ktx" } | ||
| androidx-datastore = { module = "androidx.datastore:datastore-preferences", version.ref = "androidx-datastore" } | ||
|
|
||
| # CameraX | ||
| androidx-camera-camera2 = { module = "androidx.camera:camera-camera2", version.ref = "cameraX" } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.