본문 바로가기
iOS

[로그인] KeyChain으로 토큰 저장하기 (UserDefault와의 차이점)

by 개발하는 감자입니다 2024. 4. 7.
728x90

 

안녕하세요! 개발감자입니다.

앱의 로그인 기능을 구현하면서 토큰을 저장하는 방법에 대해 고민이 많았습니다. 어떻게 저장해야 하는지 고민해보며 작성해본 글이니, 토큰을 저장하려고 하는 분들께 도움이 되었으면 합니다.

1. 토큰 저장 방법 ( UserDefault, KeyChain )

 

1-1. UserDefault

UserDefault는 간단한 데이터를 키-값 쌍으로 저장하는 데 사용되는 인터페이스입니다. 앱의 설정 같은 가벼운 데이터를 저장하기에 적합합니다. 하지만, 중요한 정보를 저장하기에는 암호화되지 않은 채로 데이터를 저장하기 때문에 보안에 취약합니다.

 

1-2. KeyChain

KeyChain은 iOS에서 제공하는 보안 저장소로, 사용자의 비밀번호, 암호화 키, 인증 토큰 같은 민감한 정보를 저장하기 위해 설계되었습니다. KeyChain에 저장된 데이터는 암호화되며, 디바이스에 안전하게 저장됩니다.

 

1-3. UserDefault와 KeyChaind의 차이점

  • 보안성: KeyChain은 암호화하여 데이터를 저장하여 보안성이 높으나, UserDefault는 암호화하지 않고 저장합니다.
  • 사용 용도: UserDefault는 설정 값 같은 비교적 민감하지 않은 데이터를 저장하는 데 적합하고, KeyChain은 로그인 정보와 같은 민감한 데이터를 저장하는 데 사용됩니다.
  • 데이터 생명주기: KeyChain에 저장된 데이터는 앱을 삭제해도 남아 있지만, UserDefault의 데이터는 앱 삭제 시 함께 제거됩니다.

UserDefault는 구현하기에는 쉽지만, 보안과 생명주기 측면에서 KeyChain보다 안정성이 떨어집니다. 더 안전한 토큰 관리를 원하신다면 KeyChain으로 구현하는 것이 좋습니다.

 

2. 구현 : KeyChaind으로 토큰 관리하기 (선언, 저장, 삭제)

 

KeyChainAccess 라이브러리를 사용하여 TokenManager 클래스를 구현하면, 애플리케이션의 보안을 강화할 수 있습니다. 다음은 TokenManager 클래스의 구현 예시입니다.

 

GitHub - kishikawakatsumi/KeychainAccess: Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS.

Simple Swift wrapper for Keychain that works on iOS, watchOS, tvOS and macOS. - kishikawakatsumi/KeychainAccess

github.com

 

com.example...의 부분의 앱의 Bundle ID를 넣으시면 됩니다.

엑세스 토큰과 리프레쉬 토큰을 선언, 저장, 삭제 그리고 로그인 여부 확인까지 구현되어 있는 예제입니다.

import Foundation
import KeychainAccess

class TokenManager {
    static let shared = TokenManager()
    private let keychain = Keychain(service: "com.example....")

    var accessToken: String? {
        get { try? keychain.get("accessToken") }
        set { try? keychain.set(newValue ?? "", key: "accessToken") }
    }

    var refreshToken: String? {
        get { try? keychain.get("refreshToken") }
        set { try? keychain.set(newValue ?? "", key: "refreshToken") }
    }
    
    func isLoggedIn() -> Bool {
        return accessToken != nil
    }

    func handleLoginSuccess(accessToken: String, refreshToken: String) {
        self.accessToken = accessToken
        self.refreshToken = refreshToken
    }

    func clearTokens() {
        do {
            try keychain.remove("accessToken")
            try keychain.remove("refreshToken")
        } catch let error {
            print("토큰 삭제 중 오류 발생: \(error)")
        }
    }
}

3. 결론

애플리케이션의 보안을 강화하고, 사용자 데이터를 안전하게 관리하기 위해서는 KeyChain을 사용하는 것이 바람직합니다. TokenManager 클래스의 구현을 통해, 애플리케이션에서 보안성 높은 토큰 관리를 실현할 수 있습니다.

728x90
반응형