[Android] 앱 내부에 accessToken 저장하는 방법

Sdoubleu·2024년 6월 26일
0

Android

목록 보기
10/16
post-thumbnail

서버에 로그인을 하게 되면 accessToken과 refreshToken을 발급해 주는데
우리는 accessToken을 통해 서버와 통신을 하므로 항상 가지고 있어야 한다 !
간단한 방법으로 앱 내부에 저장을 해서 사용하는 법을 알아보자 !


build.gradle(:app)

    // EncryptedSharedPreference
    implementation ("androidx.security:security-crypto:1.1.0-alpha06")

Module

@Module
@InstallIn(SingletonComponent::class)
class AppModule {

    @Provides
    @Singleton
    fun provideEncryptedSharedPreferences(
        @ApplicationContext context: Context,
    ): SharedPreferences {
        val masterKey = MasterKey.Builder(context)
            .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
            .build()

        val prefFileName = "encrypted_prefs"

        return EncryptedSharedPreferences.create(
            context,
            prefFileName,
            masterKey,
            EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
            EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        )
    }
}

hilt를 사용하여 암호화된 SharedPreferences를 제공하는 방법입니다

  • @Provides
    Hilt에게 이 함수가 의존성 주입을 위한 객체를 제공하는 함수임을 알려줍니다

  • @Singleton
    Hilt에게 이 함수가 제공하는 객체가 애플리케이션 전역에서 단 하나만 생성되고 재사용되어야 함을 명시합니다

  • provideEncryptedSharedPreferences 함수
    암호화된 SharedPreferences 객체를 생성하여 제공

  • @ApplicationContext context: Context
    Hilt가 애플리케이션 Context를 주입하도록 합니다

  • MasterKey.Builder(context)
    암호화에 사용할 마스터 키를 생성하는 객체
    이 객체는 암호화된 SharedPreferences 에서 데이터를 암호화하고 해독하는 데 사용합니다

  • .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
    마스터 키를 생성할 때 사용할 키 스키마를 설정
    AES256_GCM 스키마를 사용하여 AES-256-GCM 알고리즘으로 키를 생성합니다

  • val prefFileName = "encrypted_prefs"
    본인이 사용할 SharedPreferences 파일의 이름

  • EncryptedSharedPreferences.create
    암호화된 SharedPreferences 객체를 생성하는 정적 메서드

  • EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV
    SharedPreferences 키를 암호화하는 데 사용할 암호화 스키마를 지정합니다
    여기서는 AES256_SIV 스키마를 사용합니다

  • EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
    SharedPreferences 값을 암호화하는 데 사용할 암호화 스키마를 지정합니다
    여기서는 AES256_GCM 스키마를 사용합니다


SharedPreferences 저장하는 코드

class LocalUserDataSourceImpl @Inject constructor(
    private val sharedPreferences: SharedPreferences,
) : LocalUserDataSource {
    override suspend fun saveToken(provider: String, token: LoginResponse) {
        withContext(Dispatchers.IO) {
            sharedPreferences.edit().apply {
                putString("provider", provider)
                putString("ApiAccessToken", token.accessToken)
                putString("ApiRefreshToken", token.refreshToken)
            }.commit()
        }
    }
}

저장할 곳에서 Hilt로 SharedPreferences를 주입받고 사용할 곳에서 아래와 같이 사용해 주시면 됩니다

// 동기식 , 호출 시 블로킹
            sharedPreferences.edit().apply {
                putString("키",)
            }.commit()
        }
- - - - - - - - - - - - - - - - - - - - - - - - - -
// 비동기식, 호출 시 비블로킹
            sharedPreferences.edit().apply {
                putString("키",)
            }.apply()
       }
}

두 방식 모두 안전하게 사용될 수 있지만, 일반적으로 SharedPreferences 변경 사항을 저장할 때는 apply()를 사용하는 것이 권장됩니다
apply()는 더 효율적이고, 불필요한 블로킹을 피할 수 있습니다


SharedPreferences 사용하는 코드

class ProfileGetDataSourceImpl @Inject constructor(
    private val profileInfoGetApi: ProfileInfoGetApi,
    private val accessToken: SharedPreferences,
): ProfileGetDataSource{
    override suspend fun getInformation(): ApiResult<ProfileResponse> {
    
        ...
        return try {
            val profileInfoGetResponse = profileInfoGetApi.getInformation(
                accessToken.getString("ApiAccessToken", null),
            )
            
            ...
            
            }

        } catch (e: Exception) {
            ...
        }
    }

}

사용할 곳에서 Hilt로 SharedPreferences를 주입받고 사용할 곳에서 아래와 같이 사용해 주시면 됩니다

accessToken.getString("키", null)

뒤에 null을 넣은 이유는 "키"에 해당하는 값이 존재하지 않을 때
null을 반환하도록 하기 위해서 입니다


✏️

중요하지만 간단한 데이터를 저장하기 위해서 여러 가지 데이터 저장 방식을 고민해봤을 때
SharedPreferences는 간단하고, 경량이며, 사용하기 쉬운 데이터 저장 방법으로 제가 하고있는 프로젝트에서 강점이 있다고 생각했습니다
특히, EncryptedSharedPreferences를 사용하면 보안성을 높일 수 있어 민감한 데이터를 안전하게 저장할 수 있습니다

데이터 저장 방식 비교

profile
개발자희망자

0개의 댓글

관련 채용 정보