iOS : 앱 내에 사용자 이름 / 암호를 저장하는 방법


276

iOS 앱에 로그인 화면이 있습니다. 사용자 이름과 비밀번호는에 다시 저장되고 NSUserDefaults앱을 다시 입력 할 때 로그인 화면에 다시로드됩니다 (물론 NSUserDefaults영구적 임).

이제 사용자는 사용자 이름 / 암호 저장 기능을 비활성화 할 수 있습니다.

그래서 NSUserDefaults그때는 지워질 것입니다.

그러나 내 응용 프로그램에는 사용자의 데이터베이스 쿼리 에이 사용자 이름 / 암호가 필요합니다. 따라서 : 제외하고 데이터를 저장할 위치는 NSUserDefaults? (이 장소는 사용자가 앱을 종료하거나 로그 아웃 할 때 삭제해야합니다.)


사용자는 기기를 재설정하거나 앱을 제거해야만 기기를 지울 수 있습니다. 뭔가 빠졌습니까?

3
그런데 사용자가 앱을 종료 할 때 데이터를 삭제해야한다면 왜 RAM에 보관하지 않습니까?

10
NSUserDefaults 대신 사용자 이름과 비밀번호를 저장하기 위해 Keychain을 사용하는 것을 고려해야합니다.
Filip Radelic


항상 kSecValueData 및 kSecValueData를 키로 사용해야합니까? 아니면 어떤 문자열을 키로 사용할 수 있습니까?
Ne AS

답변:


424

항상 키 체인을 사용하여 사용자 이름과 비밀번호를 저장해야하며, 사용자 이름과 비밀번호는 안전하게 저장되고 앱에서만 액세스 할 수 있으므로 앱이 종료 될 때 (필요한 경우) 삭제할 필요가 없습니다.

Apple은 키 체인 항목을 저장, 읽기 및 삭제하는 샘플 코드 를 제공 하며 키 체인 사용을 크게 단순화하는 샘플에서 키 체인 래퍼 클래스를 사용하는 방법은 다음과 같습니다.

Security.framework를 포함하십시오 (Xcode 3에서 frameworks 폴더를 마우스 오른쪽 버튼으로 클릭하고 기존 프레임 워크를 추가하십시오. Xcode 4에서 프로젝트를 선택한 다음 대상을 선택하고 Build Phases 탭으로 이동 한 다음 Link Binary with Files 아래에서 +를 클릭하십시오) 및 KeychainItemWrapper .h &. m 파일을 프로젝트로 # 키 체인을 사용해야하는 곳마다 .h 파일을 가져온 다음이 클래스의 인스턴스를 만듭니다.

KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];

( YourAppLogin 은 키 체인 아이템을 호출하기 위해 선택한 모든 것이 될 수 있으며 필요한 경우 여러 아이템을 가질 수 있습니다)

그런 다음 다음을 사용하여 사용자 이름과 비밀번호를 설정할 수 있습니다.

[keychainItem setObject:@"password you are saving" forKey:kSecValueData];
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];

다음을 사용하여 가져 오십시오.

NSString *password = [keychainItem objectForKey:kSecValueData];
NSString *username = [keychainItem objectForKey:kSecAttrAccount];

또는 다음을 사용하여 삭제하십시오.

[keychainItem resetKeychainItem];

5
코드와 설명으로 답변을 업데이트했습니다. 생각만큼 어렵지 않습니다.
Filip Radelic 11

44
공격! "keykeyItemWrapper 복사"로는 충분하지 않다는 답을 추가하십시오! 나는 나중에 그것을 만들 수 없다는 문제가있었습니다! KeychainItemWrapper가 작동 할 프로젝트에 security.framework를 추가해야합니다! (방법 : 프로젝트 선택-> 대상 선택-> "빌드 단계"탭 선택-> "바이너리와 바이너리 연결"선택-> "+"-> Security.Framework 추가)
Kovu

63
ARC를 사용할 때 컴파일러는 상수 kSecValueDatakSecAttrAccountObjective-C 코드 를 사용하여 소리를 지르 므로 다음과 같이 사용하십시오 (__bridge id). [keychainItem setObject:obj forKey:(__bridge id)kSecValueData];
Joe Hankin

7
KeychainItemWrapper.m은 196 행에서 메모리 누수가있는 것 같습니다. "self.keychainItemData = [[[NSMutableDictionary alloc] init] autorelease];" 그것을 고치십시오.
Olof 2016 년

12
ARC를 사용하는 경우 업데이트 된 코드가 주어졌다 여기에 애플. 목록 2-1을보십시오. 접근 방식은 동일하지만.
Rick


48

키 체인 을 통한 매우 쉬운 솔루션 .

시스템 키 체인을위한 간단한 래퍼입니다. 그냥 추가 SSKeychain.h, SSKeychain.m, SSKeychainQuery.hSSKeychainQuery.m프로젝트에 파일을 당신의 목표에 Security.framework를 추가합니다.

비밀번호를 저장하려면

[SSKeychain setPassword:@"AnyPassword" forService:@"AnyService" account:@"AnyUser"]

비밀번호를 검색하려면 다음을 수행하십시오.

NSString *password = [SSKeychain passwordForService:@"AnyService" account:@"AnyUser"];

setPassword저장하려는 값은 어디에 있고 저장하려는 forService변수는 어디에 있고 계정은 암호 및 기타 정보의 사용자 / 개체에 대한 것입니다.


sskeychain을 사용하여 동일한 사용자 이름 및 비밀번호로 앱을 동기화하는 방법을 알고 있습니까?
Joe Shamuraq

4
비밀번호 외에 사용자 이름을 어떻게 저장합니까? SSKeychain에서 전체 계정을 어떻게 삭제합니까? 둘 다 문서에 언급되어 있지 않습니다
user798719

2
사용자 이름을 얻으려면 NSString *username = [[SSKeychain accountsForService:@"AnyService"][0] valueForKey:@"acct"]. 하나의 계정 만 사용하면 제대로 작동합니다. 항상 그렇듯이 인덱스 0에 액세스하기 전에 배열 길이를 확인하십시오.
Jared Price

27

당신은 간단하게 사용할 수 있습니다 NSURLCredential, 그것은 단지 두 줄의 코드로 키 체인에 사용자 이름과 암호를 모두 저장합니다 .

자세한 답변을 참조하십시오 .


13

Obj-C와 ARC를 사용하여 iOS 8에서 키 체인을 사용하는 방법에 대답하기로 결정했습니다.

1) GIST의 keychainItemWrapper (ARCifief 버전)를 사용했습니다 : https://gist.github.com/dhoerl/1170641/download-KeychainItemWrapper.h 및 .m을 프로젝트에 추가 (+ 복사)하십시오.

2) 프로젝트에 보안 프레임 워크 추가 (프로젝트> 빌드 단계> 바이너리와 라이브러리 링크 확인)

3) 키 체인을 사용하려는 .h 및 .m 파일에 보안 라이브러리 (#import) 및 KeychainItemWrapper (#import "KeychainItemWrapper.h")를 추가하십시오.

4) 키 체인에 데이터를 저장하려면 :

NSString *emailAddress = self.txtEmail.text;
NSString *password = self.txtPasword.text;
//because keychain saves password as NSData object
NSData *pwdData = [password dataUsingEncoding:NSUTF8StringEncoding];

//Save item
self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[self.keychainItem setObject:emailAddress forKey:(__bridge id)(kSecAttrAccount)];
[self.keychainItem setObject:pwdData forKey:(__bridge id)(kSecValueData)];

5) 데이터 읽기 (로드시 로그인 화면> viewDidLoad) :

self.keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];

self.txtEmail.text = [self.keychainItem objectForKey:(__bridge id)(kSecAttrAccount)];

//because label uses NSString and password is NSData object, conversion necessary
NSData *pwdData = [self.keychainItem objectForKey:(__bridge id)(kSecValueData)];
NSString *password = [[NSString alloc] initWithData:pwdData encoding:NSUTF8StringEncoding];
self.txtPassword.text = password;

즐겨!


11

키 체인 래퍼를 사용하여 비밀번호를 검색하는 데 문제가있는 경우 다음 코드를 사용하십시오.

NSData *pass =[keychain objectForKey:(__bridge id)(kSecValueData)];
NSString *passworddecoded = [[NSString alloc] initWithData:pass
                                           encoding:NSUTF8StringEncoding];


2

이거 한번 해봐:

 KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData]; 
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];

도움이 될 것입니다.


2

KeychainItemWrapper (ARC 버전)를 사용하는 것을 보았지만 원하는 Objective C 래퍼를 찾지 못했습니다.

내가 사용하는 이 솔루션 에 의해 키시 카와 카츠미 내가 적은 코드를 작성하고있는 NSString 값을 저장하기 위해 캐스트를 사용하지 않은 의미.

저장의 두 가지 예 :

[UICKeyChainStore setString:@"kishikawakatsumi" forKey:@"username"];
[UICKeyChainStore setString:@"P455_w0rd$1$G$Z$" forKey:@"password"];

검색의 두 가지 예

UICKeyChainStore *store = [UICKeyChainStore keyChainStore];
    // or
UICKeyChainStore *store = [UICKeyChainStore keyChainStoreWithService:@"YOUR_SERVICE"];

NSString *username = [store stringForKey:@"username"];
NSString *password = [store stringForKey:@"password"];

2

위의 코드에는 작은 버그가 있습니다 (Dave가 귀하의 게시물에 감사하는 데 매우 도움이되었습니다)

자격 증명을 저장하는 부분에서 제대로 작동하려면 다음 코드도 필요합니다.

[self.keychainItem setObject:@"myCredentials" forKey:(__bridge id)(kSecAttrService)];

아마도 우리가 두 번째로 키 체인 항목에 이미 할당 된 것과 동일한 자격 증명으로 다시 로그인하려고 시도 할 때 앱이 충돌하기 때문일 수 있습니다. 위의 코드를 사용하면 매력처럼 작동합니다.


2

이 질문을 업데이트하려면

Swift 체크 아웃을 사용하는 사용자의 경우 액세스 그룹을 지원하는 Mihai Costea의이 드래그 앤 드롭 신속한 구현 :

https://github.com/macostea/KeychainItemWrapper.swift/blob/master/KeychainItemWrapper.swift

키 체인을 사용하기 전에 : 비밀번호를 저장하기 전에 두 번 고려하십시오. 인증 토큰 (예 : 지속성 세션 ID)과 전자 메일 또는 계정 이름을 저장하면 충분할 수 있습니다. 인증 토큰을 쉽게 무효화하여 무단 액세스를 차단할 수 있으므로 사용자는 손상된 장치에서 다시 로그인해야하지만 암호 재설정이 필요하지 않고 모든 장치에서 다시 로그인해야합니다 (우리는 Apple을 사용하고 있습니까?).


1

그러나 이제 키 체인 래퍼 대신 NURLCredential을 사용할 수 있습니다. 우리가해야 할 일을합니다.



0

다음은 잘 작동합니다.

KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"YourAppLogin" accessGroup:nil];
[keychainItem setObject:@"password you are saving" forKey:kSecValueData]; 
[keychainItem setObject:@"username you are saving" forKey:kSecAttrAccount];
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.