iOS: ऐप के भीतर यूज़रनेम / पासवर्ड कैसे स्टोर करें?


276

मेरे iOS ऐप में एक लॉगिन-स्क्रीन है। NSUserDefaultsजब आप फिर से ऐप में प्रवेश करेंगे (तब, निश्चित NSUserDefaultsरूप से स्थायी हैं) उपयोगकर्ता नाम और पासवर्ड को फिर से लॉगिन-स्क्रीन में लोड किया जाएगा ।

अब, उपयोगकर्ता के पास उपयोगकर्ता नाम / पासवर्ड बचत सुविधा को अक्षम करने की संभावना है।

तो NSUserDefaultsवसीयत को मंजूरी दे दी जाएगी।

लेकिन मेरे ऐप में उपयोगकर्ता के लिए डेटाबेस प्रश्नों के लिए मुझे इस उपयोगकर्ता नाम / पासवर्ड की आवश्यकता है। तो: डेटा को कहां स्टोर करना है NSUserDefaults? (उपयोगकर्ता द्वारा ऐप या लॉगआउट छोड़ने पर इस स्थान को हटा दिया जा सकता है)।


उपयोगकर्ता केवल डिवाइस को रीसेट करने या ऐप को हटाकर इसे साफ कर सकता है। क्या मैं कुछ भूल रहा हूँ?

3
और वैसे, जब उपयोगकर्ता ऐप को छोड़ता है तो डेटा को हटा दिया जाना चाहिए, बस इसे रैम में क्यों न रखें?

10
आपको NSUserDefaults के बजाय उपयोगकर्ता नाम और पासवर्ड संग्रहीत करने के लिए किचेन का उपयोग करने पर गंभीरता से विचार करना चाहिए।
फ़िलिप रेडिकेल


कृपया मुझे हमेशा कुंजी के रूप में kSecValueData और kSecValueData का उपयोग करना चाहिए? या मैं एक कुंजी के रूप में किसी भी स्ट्रिंग का उपयोग कर सकता हूं?
Ne AS

जवाबों:


424

आपको उपयोगकर्ता नाम और पासवर्ड को संग्रहीत करने के लिए हमेशा किचेन का उपयोग करना चाहिए, और चूंकि यह सुरक्षित रूप से संग्रहीत है और केवल आपके ऐप के लिए सुलभ है, ऐप के क्विट होने पर इसे हटाने की कोई आवश्यकता नहीं है (यदि वह आपकी चिंता थी)।

Apple नमूना कोड प्रदान करता है जो किचेन आइटमों को संग्रहीत, पढ़ता है और हटाता है और यहां बताया गया है कि उस नमूने से चाबी का गुच्छा आवरण वर्ग का उपयोग कैसे किया जाए जो किचेन के उपयोग को सरल करता है।

Security.framework शामिल करें (Xcode 3 में चौखटे फ़ोल्डर पर राइट-क्लिक करें और मौजूदा फ्रेमवर्क जोड़ें। Xcode 4 में अपनी परियोजना का चयन करें, फिर लक्ष्य का चयन करें, बिल्ड चरणों में जाएं और + लिंक के तहत + लिंक बाइनरी विद फाइल्स पर क्लिक करें) और KeychainemWrapper .h & & अपने प्रोजेक्ट में m फ़ाइलें, #import .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
मैंने कोड और विवरण के साथ अपना उत्तर अपडेट कर दिया है। यह लगभग उतना कठिन नहीं है जितना आपने सोचा था।
फ़िलिप रेडिकेल

44
ATTANTION! कृपया अपने उत्तर में जोड़ें, कि केवल "कॉपी कीचेनइमवेयर" की प्रतिलिपि पर्याप्त नहीं है! मुझे समस्या थी, कि मैं बाद में इसका निर्माण नहीं कर सकता! आपको अपने प्रोजेक्ट में Security.framework को जोड़ना होगा कि KeychainItemWrapper काम करेगा! (HowTo: प्रोजेक्ट का चयन करें -> टार्गेट चुनें -> टैब चुनें "बिल्ड चरणों" -> "लीबरीज़ के साथ लिंक बाइनरी" का चयन करें -> "" + "-> सुरक्षा जोड़ें। सुरक्षा)
कोवू

63
एआरसी का उपयोग करते समय, कंसीलर kSecValueDataऔर kSecAttrAccountऑब्जेक्टिव-सी कोड का उपयोग करने के लिए कंपाइलर आप पर चिल्लाएगा , इसलिए उनका उपयोग करना सुनिश्चित करें (__bridge id), जैसे, [keychainItem setObject:obj forKey:(__bridge id)kSecValueData];
जो हांकिन

7
KeychainItemWrapper.m को 196 की लाइन पर मेमोरी लीक होती है। लाइन को "self.keychainItemData = [[[NSMutableDictionary आवंटित] init] ऑटोरेलिज];" इसे ठीक करता है।
ओलोफ

12
ARC का उपयोग करते समय अद्यतन कोड यहाँ Apple द्वारा दिया गया है । सूची 2-1 देखें। हालांकि दृष्टिकोण एक ही है।
रिक


48

किचेन के माध्यम से एक बहुत ही आसान उपाय ।

यह सिस्टम किचेन के लिए एक साधारण आवरण है। बस जोड़ने SSKeychain.h, SSKeychain.m, SSKeychainQuery.hऔर SSKeychainQuery.mअपनी परियोजना के लिए फ़ाइलों और अपने लक्ष्य को Security.framework जोड़ें।

पासवर्ड बचाने के लिए:

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

पासवर्ड पुनः प्राप्त करने के लिए:

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

कहाँ setPasswordक्या आप को बचाया और चाहते मूल्य है forServiceक्या चर आप इसे अंतर्गत सहेजा और खाता उपयोगकर्ता क्या / पासवर्ड वस्तु और किसी भी अन्य जानकारी के लिए है चाहता हूँ।


क्या आप जानते हैं कि एक ही उपयोगकर्ता नाम और पासवर्ड के साथ एप्लिकेशन को सिंक्रनाइज़ करने के लिए sskeychain का उपयोग कैसे करें?
जो शमुरुक

4
आप एक यूज़रनेम और पासवर्ड के अलावा स्टोर कैसे कर सकते हैं? आप SSKeychain से एक संपूर्ण खाता कैसे हटाते हैं? दोनों का उल्लेख नहीं है डॉक्स
user798719

2
उपयोगकर्ता नाम प्राप्त करने के लिए NSString *username = [[SSKeychain accountsForService:@"AnyService"][0] valueForKey:@"acct"]। यह ठीक काम करना चाहिए अगर आप केवल एक खाते का उपयोग करते हैं। हमेशा की तरह, सूचकांक 0. तक पहुंचने की कोशिश करने से पहले सरणी की लंबाई की जांच करना सुनिश्चित करें।
जारेड प्राइस

27

आप बस उपयोग कर सकते हैं NSURLCredential, यह कोडकिन में केवल दो लाइनों में उपयोगकर्ता नाम और पासवर्ड दोनों को बचाएगा

मेरी विस्तृत देखें जवाब


13

मैंने ओज-सी और एआरसी का उपयोग करके आईओएस 8 में किचेन का उपयोग करने का जवाब देने का फैसला किया।

1) मैंने GIST से keychainItemWrapper (ARCifief संस्करण) का उपयोग किया: https://gist.github.com/dhoerl/1170641/download - KeychainItemWrapper.h और .m अपने प्रोजेक्ट में जोड़ें।

2) अपनी परियोजना में सुरक्षा ढांचा जोड़ें (परियोजना में जाँच करें> चरण बनाएँ> पुस्तकालयों के साथ लिंक बाइनरी)

3) सुरक्षा लाइब्रेरी (#import) और KeychainItemWrapper (#import "KeychainItemWrapper.h") को .h .m फ़ाइल में जोड़ें और जहाँ आप कीचेन का उपयोग करना चाहते हैं।

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 संस्करण) का उपयोग करते हुए देखा, लेकिन मुझे वांछित के रूप में इसका उद्देश्य C आवरण नहीं मिला।

मैंने इस समाधान का उपयोग किशिकावा कट्सुमी द्वारा किया था, जिसका मतलब था कि मैंने कम कोड लिखा था और एनएसएसएसआरिंग मूल्यों को संग्रहीत करने के लिए जातियों का उपयोग नहीं करना था।

भंडारण के दो उदाहरण:

[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

उपरोक्त कोड में एक छोटा सा बग है (जिस तरह से डेव ने आपकी पोस्ट को धन्यवाद दिया वह बहुत उपयोगी था)

जिस हिस्से में हम साख बचाते हैं, उसे ठीक से काम करने के लिए निम्न कोड की भी आवश्यकता होती है।

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

शायद इसलिए क्योंकि दूसरी बार जब हम उसी क्रेडेंशियल्स के साथ साइन (पुनः) साइन इन करने की कोशिश करते हैं, तो यह पता चलता है कि उन्हें किचेन आइटम में पहले से ही असाइन किया गया है और ऐप क्रैश हो गया है। उपरोक्त कोड के साथ यह एक आकर्षण की तरह काम करता है।


2

इस प्रश्न को अद्यतन करने के लिए:

स्विफ्ट चेकआउट का उपयोग करने वालों के लिए मिहाई कोस्टिया द्वारा पहुँच समूहों का समर्थन करते हुए इस ड्रैग और ड्रॉप स्विफ्ट कार्यान्वयन को:

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

किचेन का उपयोग करने से पहले: पासवर्ड को स्टोर करने से पहले दो बार विचार करें। कई मामलों में एक प्रमाणीकरण टोकन (जैसे एक दृढ़ता सत्र आईडी) और ईमेल या खाते का नाम पर्याप्त हो सकता है। आप अनधिकृत पहुंच को ब्लॉक करने के लिए प्रमाणीकरण टोकन को आसानी से अमान्य कर सकते हैं, उपयोगकर्ता को समझौता किए गए डिवाइस पर फिर से लॉगिन करने की आवश्यकता होती है, लेकिन रीसेट पासवर्ड की आवश्यकता नहीं होती है और सभी उपकरणों पर फिर से लॉगिन करने की आवश्यकता होती है (हम केवल ऐप्पल का उपयोग नहीं कर रहे हैं?)।


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];
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.