알고가자 !
키체인을 알아보기 전에 토큰에 대해 알아보자.
✅ 토큰(Token)
토큰은 사용자의 신원을 증명하고 서버에 접근 권한을 부여하는 암호화된 문자열이다. 기존의 세션-쿠키 방식과 달리, 서버가 클라이언트의 상태를 저장하지 않는 무상태 인증(Stateless) 방식이다.
✅ JWT(JSON Web Token)
JWT는 토큰의 대표적인 형식으로, JSON 객체를 암호화하여 만든 문자열이다. Header(토큰 타입, 암호화 알고리즘), Payload(사용자 정보, 권한 등), Signature(위변조 검증용) 세 부분으로 구성된다.
✅ 액세스 토큰(Access Token)
액세스 토큰은 실제로 보호된 리소스에 접근할 때 사용하는 토큰이다. 탈취되더라도 피해를 최소화하기 위해 짧은 유효기간(보통 30분 ~ 2시간)을 설정한다.
✅ 리프레시 토큰(Refresh Token)
리프레시 토큰은 액세스 토큰이 만료되었을 때 새로운 액세스 토큰을 발급받기 위한 토큰이다. 비교적 긴 유효기간(보통 2주 ~ 수개월)을 가지며, 보안이 더 중요하므로 안전한 저장소에 보관해야 한다.
✅ OAuth 2.0
OAuth는 제3자 애플리케이션이 사용자의 리소스에 접근할 수 있도록 하는 표준 프로토콜이다. 예를 들어 소셜 로그인(카카오, 구글 등)으로 다른 서비스를 이용하는 것을 말한다.
KeyChain
키체인은 iOS의 암호화된 데이터베이스로, 민감한 사용자 정보를 안전하게 저장하기 위한 시스템 수준의 보안 저장소이다. 암호, 인증서, 암호화 키, 토큰 등 민감한 데이터를 저장하는 데 사용된다. 데이터는 기기의 보안 하드웨어를 이용해 암호화되어 저장된다.
✅ KeyChain의 주요 특징
1. 암호화 저장 : 데이터가 자동으로 암호화되어 저장된다.
2. 영속성 : 앱을 삭제하더라도 데이터가 유지된다. (설정에 따라 다르다.)
3. 보안성 : 시스템 레벨에서 관리되어 높은 보안성을 제공한다.
4. 공유 가능 : 같은 개발자의 다른 앱과 데이터 공유가 가능하다.
✅ KeyChain Item의 속성들
✔️ kSecClass(저장할 데이터 유형) : 키체인에 저장할 데이터의 종류를 지정하는 필수 속성
주요 타입
- kSecClassGenericPassword : 일반적인 비밀번호나 문자열 데이터 (일반적인 토큰 저장 시에 사용)
- kSecClassInternetPassword : 인터넷 관련 비밀번호
- kSecClassCertificate : 인증서
- kSecClassKey : 암호화 키
- kSecClassIdentity : 인증서와 개인키 쌍
✔️ kSecAttrAccount(계정 식별자) : 저장된 항목을 식별하는 데 사용되는 문자열으로 같은 서비스내에서 여러 계정을 구분할 때 사용
// 여러 사용자의 토큰을 구분하여 저장
kSecAttrAccount: "user1_access_token"
kSecAttrAccount: "user1_refresh_token"
kSecAttrAccount: "user2_access_token"
✔️ kSecAttrService(서비스 식별자) : 항목이 속한 서비스를 식별하는 문자열으로 보통 앱의 번들 ID나 서비스 도메인을 사용한다.
// 서비스별로 데이터 구분
kSecAttrService: "com.myapp.authentication"
kSecAttrService: "com.myapp.payment"
✔️ kSecValueData(저장 데이터) : 실제로 저장할 데이터 값으로, 반드시 Data 타입으로 변환해야 한다.
// 문자열을 Data로 변환하여 저장
let token = "eyJhbGciOiJIUzI1NiIs..."
let tokenData = token.data(using: .utf8)!
kSecValueData: tokenData
// 객체를 JSON으로 인코딩하여 저장
let userData = try? JSONEncoder().encode(user)
kSecValueData: userData
✔️ kSecAttrAccessible(데이터 접근 정책) : 데이터에 접근할 수 있는 조건을 지정
주요 옵션
- kSecAttrAccessibleAfterFirstUnlock : 기기 잠금 해제 후 항상 접근 가능
- kSecAttrAccessibleWhenUnlockedThisDeviceOnly : 현재 기기에서만, 잠금 해제 상태에서만 접근 가능
- kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly : 현재 기기에서만, 잠금 해제 후 항상 접근 가능
- kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly : 패스코드 설정된 기기에서만 접근 가능
✔️ kSecAttrSynchronizable(iCloud 동기화) : iCloud를 통한 키체인 항목 동기화 여부로, Bool 값으로 지정한다.
// iCloud 동기화 활성화
kSecAttrSynchronizable: true
// 동기화 비활성화 (기본값)
kSecAttrSynchronizable: false
// 동기화 항목 조회 시
kSecAttrSynchronizable: kSecAttrSynchronizableAny
간단한 사용 예제
let query: [String: Any] = [
// 일반 비밀번호 타입으로 저장
kSecClass as String: kSecClassGenericPassword,
// "accessToken"이라는 계정 식별자로 저장
kSecAttrAccount as String: "accessToken",
// 앱의 인증 서비스용으로 지정
kSecAttrService as String: "com.myapp.authentication",
// 실제 토큰 데이터
kSecValueData as String: tokenString.data(using: .utf8)!,
// 잠금 해제 후 접근 가능하도록 설정
kSecAttrAccessible as String: kSecAttrAccessibleAfterFirstUnlock,
// iCloud 동기화 비활성화
kSecAttrSynchronizable as String: false
]
// Keychain에 저장
let status = SecItemAdd(query as CFDictionary, nil)
'iOS' 카테고리의 다른 글
[iOS] 앱스토어에 앱을 출시해보자 (0) | 2024.01.27 |
---|---|
[iOS] Identifiers(식별자) 신규 등록 (1) | 2024.01.27 |
[iOS] 간단한 날씨 앱 - MVVM + URLSession + URLComponent (1) | 2023.08.14 |