[swift] Swift에서 키체인을 사용하여 사용자 로깅 관리하기

안녕하세요! 오늘은 Swift 언어를 사용하여 사용자 로깅 관리를 위해 키체인을 사용하는 방법에 대해 알아보겠습니다.

1. Keychain이란?

Keychain은 사용자의 데이터를 안전하게 저장하기 위한 macOS 및 iOS에서 제공하는 보안 서비스입니다. Keychain은 암호화된 형태로 사용자의 개인 정보나 인증서, 비밀번호 등을 안전하게 저장할 수 있어 많은 앱에서 사용되고 있습니다.

2. Swift에서 Keychain 사용하기

Swift에서 Keychain을 사용하기 위해서는 Security.framework을 프로젝트에 추가해야 합니다. 먼저 프로젝트의 Build Phases에서 Link Binary With Libraries 섹션으로 이동하고 + 버튼을 클릭하여 Security.framework을 추가합니다.

2.1 Keychain에 데이터 저장하기

Keychain에 데이터를 저장하기 위해서는 SecItemAdd 함수를 사용합니다.

import Foundation
import Security

func saveDataToKeychain(username: String, password: String) -> OSStatus {
    let attributes: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: "myAccount",
        kSecValueData as String: password.data(using: .utf8)!,
        kSecAttrAccessible as String: kSecAttrAccessibleWhenUnlocked
    ]
    
    return SecItemAdd(attributes as CFDictionary, nil)
}

위 코드에서 kSecClassGenericPassword는 일반적인 비밀번호 타입을 의미하며, kSecAttrAccount는 계정을 식별하는 식별자입니다. kSecValueData는 저장할 데이터를 의미하고, kSecAttrAccessible는 데이터에 접근할 수 있는 제한에 대한 설정입니다.

2.2 Keychain에서 데이터 가져오기

Keychain에서 데이터를 가져오기 위해서는 SecItemCopyMatching 함수를 사용합니다.

import Foundation
import Security

func retrieveDataFromKeychain() -> String? {
    let query: [String: Any] = [
        kSecClass as String: kSecClassGenericPassword,
        kSecAttrAccount as String: "myAccount",
        kSecReturnData as String: true,
        kSecMatchLimit as String: kSecMatchLimitOne
    ]
    
    var result: AnyObject?
    let status = SecItemCopyMatching(query as CFDictionary, &result)
    
    if status == errSecSuccess, let data = result as? Data {
        return String(data: data, encoding: .utf8)
    }
    
    return nil
}

위 코드에서 kSecReturnData는 결과로 데이터를 반환할지 여부를 의미하며, kSecMatchLimitOne은 하나의 결과만 반환하도록 설정합니다.

3. 사용자 로깅 관리에 Keychain 활용하기

사용자 로깅 관리에 Keychain을 활용하기 위해, 예를 들어 사용자의 로그인 정보를 안전하게 저장하고 검증하는 과정을 구현할 수 있습니다.

import Foundation
import Security

func saveUserLoginInfo(username: String, password: String) {
    let saveStatus = saveDataToKeychain(username: username, password: password)
    if saveStatus == errSecSuccess {
        print("User login info saved successfully!")
    } else {
        print("Failed to save user login info.")
    }
}

func retrieveUserLoginInfo() -> (username: String?, password: String?) {
    guard let password = retrieveDataFromKeychain() else {
        return (nil, nil)
    }
    
    return ("myUsername", password)
}

func verifyUserLoginInfo(username: String, password: String) -> Bool {
    let storedUsername = "myUsername"
    
    if username == storedUsername {
        return password == retrieveUserLoginInfo().password
    }
    
    return false
}

위 코드에서 saveUserLoginInfo 함수는 사용자의 로그인 정보를 Keychain에 저장합니다. retrieveUserLoginInfo 함수는 Keychain에서 저장된 정보를 불러옵니다. verifyUserLoginInfo 함수는 입력된 사용자 이름과 비밀번호를 검증하여 로그인이 유효한지를 확인합니다.

마무리

Swift에서 Keychain을 사용하여 사용자 로깅 관리를 안전하게 처리하는 방법에 대해 알아보았습니다. Keychain은 사용자의 개인 정보를 보호하는 데 큰 도움이 되는 강력한 도구입니다. 이를 활용하여 앱의 보안성을 향상시킬 수 있습니다. 추가적인 기능 및 세부 설정에 대한 자세한 내용은 Apple 공식 개발자 문서를 참고하시기 바랍니다.