반응형
iOS의 키 체인에 이메일 / 비밀번호 저장
나는 iOS 개발이 처음이므로 이것이 초보자 질문이라면 용서하십시오. 사용자의 이메일 주소와 비밀번호를 사용하는 내 앱에 대한 간단한 인증 메커니즘이 있습니다. 또한 '기억하기'라는 스위치가 있습니다. 사용자가 해당 스위치를 켜면 나중에 해당 필드가 자동으로 채워질 수 있도록 이메일 / 비밀번호를 보존하고 싶습니다.
나는 plist 파일에 저장하는 작업을 위해 이것을 얻었지만 암호가 암호화되지 않았기 때문에 이것이 최선의 생각이 아니라는 것을 알고 있습니다. 키 체인에 저장하기위한 샘플 코드를 찾았지만 솔직히 말해서 좀 잃어 버렸습니다. 아래 함수의 경우 호출 방법과 이메일 주소를 저장하기 위해 수정하는 방법도 잘 모르겠습니다.
나는 그것을 부를 것이라고 생각한다. saveString(@"passwordgoeshere");
도와 주셔서 감사합니다 !!!
+ (void)saveString:(NSString *)inputString forKey:(NSString *)account {
NSAssert(account != nil, @"Invalid account");
NSAssert(inputString != nil, @"Invalid string");
NSMutableDictionary *query = [NSMutableDictionary dictionary];
[query setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[query setObject:account forKey:(id)kSecAttrAccount];
[query setObject:(id)kSecAttrAccessibleWhenUnlocked forKey:(id)kSecAttrAccessible];
OSStatus error = SecItemCopyMatching((CFDictionaryRef)query, NULL);
if (error == errSecSuccess) {
// do update
NSDictionary *attributesToUpdate = [NSDictionary dictionaryWithObject:[inputString dataUsingEncoding:NSUTF8StringEncoding]
forKey:(id)kSecValueData];
error = SecItemUpdate((CFDictionaryRef)query, (CFDictionaryRef)attributesToUpdate);
NSAssert1(error == errSecSuccess, @"SecItemUpdate failed: %d", error);
} else if (error == errSecItemNotFound) {
// do add
[query setObject:[inputString dataUsingEncoding:NSUTF8StringEncoding] forKey:(id)kSecValueData];
error = SecItemAdd((CFDictionaryRef)query, NULL);
NSAssert1(error == errSecSuccess, @"SecItemAdd failed: %d", error);
} else {
NSAssert1(NO, @"SecItemCopyMatching failed: %d", error);
}
}
NSCoding 호환 객체를 키 체인에 저장할 수있는 간단한 래퍼를 작성했습니다. 예를 들어 이메일과 암호를 NSDictionary에 저장하고이 클래스를 사용하여 NSDictionary를 키 체인에 저장할 수 있습니다.
SimpleKeychain.h
#import <Foundation/Foundation.h>
@class SimpleKeychainUserPass;
@interface SimpleKeychain : NSObject
+ (void)save:(NSString *)service data:(id)data;
+ (id)load:(NSString *)service;
+ (void)delete:(NSString *)service;
@end
SimpleKeychain.m
#import "SimpleKeychain.h"
@implementation SimpleKeychain
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassGenericPassword, (id)kSecClass,
service, (id)kSecAttrService,
service, (id)kSecAttrAccount,
(id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible,
nil];
}
+ (void)save:(NSString *)service data:(id)data {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData];
}
@catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
}
@finally {}
}
if (keyData) CFRelease(keyData);
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
}
@end
ARC 준비 코드 :
KeychainUserPass.h
#import <Foundation/Foundation.h>
@interface KeychainUserPass : NSObject
+ (void)save:(NSString *)service data:(id)data;
+ (id)load:(NSString *)service;
+ (void)delete:(NSString *)service;
@end
KeychainUserPass.m
#import "KeychainUserPass.h"
@implementation KeychainUserPass
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge id)kSecClassGenericPassword, (__bridge id)kSecClass,
service, (__bridge id)kSecAttrService,
service, (__bridge id)kSecAttrAccount,
(__bridge id)kSecAttrAccessibleAfterFirstUnlock, (__bridge id)kSecAttrAccessible,
nil];
}
+ (void)save:(NSString *)service data:(id)data {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge id)kSecValueData];
SecItemAdd((__bridge CFDictionaryRef)keychainQuery, NULL);
}
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
[keychainQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((__bridge CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
}
@catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
}
@finally {}
}
if (keyData) CFRelease(keyData);
return ret;
}
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
}
@end
참조 URL : https://stackoverflow.com/questions/5247912/saving-email-password-to-keychain-in-ios
반응형
'development' 카테고리의 다른 글
디렉터리 및 하위 디렉터리의 모든 파일을 시간 역순으로 나열하려면 어떻게합니까? (0) | 2020.12.28 |
---|---|
Ajax 호출에서 세션 시간 초과 처리 (0) | 2020.12.28 |
Traversable의 foreach 메서드에서 현재 요소의 인덱스를 가져 오나요? (0) | 2020.12.28 |
Slim PHP 및 GET 매개 변수 (0) | 2020.12.28 |
html에서 ► 재생 (앞으로) 또는 단색 오른쪽 화살표 기호를 어떻게 표시합니까? (0) | 2020.12.28 |