web-dev-qa-db-ja.com

iOS:アプリ内にユーザー名/パスワードを保存する方法

IOSアプリにログイン画面があります。ユーザー名とパスワードはNSUserDefaultsに保存され、アプリを再起動すると再びログイン画面にロードされます(もちろん、NSUserDefaultsは永続的です)。

今、ユーザーはユーザー名/パスワードの保存機能を無効にする可能性があります。

そのためNSUserDefaultsはクリアされます。

しかし、私のアプリでは、ユーザーのデータベースクエリにこのユーザー名/パスワードが必要です。だから:NSUserDefaults以外のデータをどこに格納するの? (この場所は、ユーザーがアプリを終了したりログアウトしたりするときに削除できます)。

271
Kovu

ユーザー名とパスワードの保存には常にKeychainを使用する必要があります。また、安全に保存されており、アプリからしかアクセスできないため、アプリの終了時に削除する必要はありません(心配な場合)。

Appleは サンプルコード キーチェーンアイテムの保存、読み込み、削除を提供しています。キーチェーンの使い方を非常に簡単にするそのサンプルからキーチェーンラッパークラスを使う方法があります。

Security.frameworkをインクルード(Xcode 3ではframeworksフォルダを右クリックし、既存のフレームワークを追加します。Xcode 4ではプロジェクトを選択してからターゲットを選択し、Build Phasesタブに移動してLink Binaryの下の+をクリックします。 Files)およびKeychainItemWrapperの.h&.mファイルを使用して、keychainを使用する必要がある場所に.hファイルを#importしてから、このクラスのインスタンスを作成します。

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];
420
Filip Radelic

ARCバージョンのラッパーが必要な場合は、ここにリンクがあります https://Gist.github.com/1170641 おかげで

97
Manuel Pintaldi

Keychains による非常に簡単な解決策。

これはシステムキーチェーンのシンプルなラッパーです。 SSKeychain.hSSKeychain.mSSKeychainQuery.hSSKeychainQuery.mの各ファイルをプロジェクトに追加し、Security.frameworkをターゲットに追加するだけです。

パスワードを保存するには

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

パスワードを取得するには

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

ここでsetPasswordは保存したい値、forServiceは保存したい変数、accountはパスワードを含むユーザー/オブジェクト、その他の情報です。

48
sust86

単にNSURLCredentialを使用することができます、それはちょうど2行のコードでキーチェーンにユーザー名とパスワードの両方を保存します。

私の詳細を参照してください 答え

27
Phil

Obj-CとARCを使ってiOS 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;

楽しい!

13
D_RBD

キーチェーンラッパーを使用してパスワードを取得する際に問題がある場合は、次のコードを使用してください。

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

これをチェックしてください サンプルコード 最初にサンプルコードからAppleのラッパーを試してみましたが、これは私にとってはずっと簡単です。

3
BSevo

これを試してください。

 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
Vara

この質問を更新するには

Swiftチェックアウトを使用している人のために、Mihai Costeaによる、このドラッグアンドドロップによるSwiftの実装をサポートするアクセスグループ:

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

キーチェーンを使用する前に:パスワードを保存する前に2回検討してください。多くの場合、認証トークン(永続セッションIDなど)と電子メール名またはアカウント名を格納するだけで十分です。不正なアクセスをブロックするために認証トークンを簡単に無効にすることができます。ユーザーは侵入先のデバイスに再度ログインする必要がありますが、パスワードの再設定は不要です。

2
pizzamonster

私はKeychainItemWrapper(ARC版)を使ってみましたが、Objective Cのラッパーが望みどおりに健全であるとは思いませんでした。

このソリューション by Kishikawa Katsumi を使用したので、コードの作成が少なくなり、NSString値を格納するためにキャストを使用する必要がなくなりました。

格納の2つの例

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

検索の2つの例

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

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

上記のコードには小さなバグがあります(ところでDaveは非常に役に立ちました。投稿ありがとうございます)。

認証情報を保存する部分では、正しく機能するために次のコードも必要です。

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

おそらく、2回目に同じ認証情報を使用して(再)サインインしようとすると、キーチェーン項目に割り当てられていることが判明し、アプリケーションがクラッシュするためです。上記のコードでそれは魅力のように働きます。

2
ReaLity

しかし、今、あなたはキーチェーンラッパーの代わりにNURLCredentialに行くことができます。それは我々がする必要があることをします。

1
Sumitiscreative

Swiftの場合は、このライブラリを使用できます。

https://github.com/jrendel/SwiftKeychainWrapper

Swiftのすべてのバージョンをサポートしています。

1
Ghulam Rasool

以下はうまくいくはずです。

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