zoukankan      html  css  js  c++  java
  • iOS

    1、Sign up/in

    1.1 用户登录安全原则

    • 不能在网络上传输用户隐私数据的明文。
    • 不能在本地和服务器上存储用户隐私数据的明文。

    1.2 用户登录流程

    • 登录成功之后,应该跳转视图控制器到主页。

    • 如果用户上次登录成功,启动应用程序时,直接进入主页。

    • 当用户主动注销的时候,返回登录页面。

    • 在实际开发中,关于网络方面的代码执行,通常会有一个单例统一管理。涉及到网络就涉及到多线程的异步,需要控制最大并发数。

    1.3 iOS 中加解密

    2、明文登录

    • Objective-C

      • GET 登录

        	// 用户名
        	NSString *username = self.usernameText.text;
        
        	// 用户密码明文
        	NSString *pwd = self.pwdText.text;
        
        	NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:
        	                     @"http://192.168.88.200/login/login.php?username=%@&password=%@", username, pwd]];
        	NSURLRequest *request = [NSURLRequest requestWithURL:url];
        
        	[[[NSURLSession sharedSession] dataTaskWithRequest:request 
        	                                 completionHandler:^(NSData * _Nullable data, 
        	                                              NSURLResponse * _Nullable response, 
        	                                                    NSError * _Nullable error) {
        
            	if (error == nil || data != nil) {
                	NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
                	if ([dict[@"userId"] intValue] > 0) {
        				[self saveUserLoginInfo];
                	}
            	}
        	}] resume];
        
      • POST 登录

        	// 用户名
        	NSString *username = self.usernameText.text;
        
        	// 用户密码明文
        	NSString *pwd = self.pwdText.text;
        
        	NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/login/login.php"];
        	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        	request.HTTPMethod = @"POST";
        	request.HTTPBody = [[NSString stringWithFormat:@"username=%@&password=%@", username, pwd] 
        	                                                  dataUsingEncoding:NSUTF8StringEncoding];
        	
        	[[[NSURLSession sharedSession] dataTaskWithRequest:request 
        	                                 completionHandler:^(NSData * _Nullable data, 
        	                                              NSURLResponse * _Nullable response, 
        	                                                    NSError * _Nullable error) {
            
            	if (error == nil || data != nil) {
                	NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
                	if ([dict[@"userId"] intValue] > 0) {
        				[self saveUserLoginInfo];
                	}
            	}
        	}] resume];
        

    3、Base64 编码登录

    • Base64 编码具体实现代码见 GitHub 源码 QExtension

    • Objective-C

      • NSString+Base64.m

        	// 对 ASCII 编码的字符串进行 base64 编码
        	- (NSString *)base64Encode {
        
            	NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];               
            	return [data base64EncodedStringWithOptions:0];
        	}
        
        	// 对 base64 编码的字符串进行解码
        	- (NSString *)base64Decode {
        
            	NSData *data = [[NSData alloc] initWithBase64EncodedString:self options:0];
            	return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        	}
        
      • POST 登录

        	// 用户名
        	NSString *username = self.usernameText.text;
        
        	// 经 base64 编码的用户密码
        	NSString *pwd = [self.pwdText.text base64Encode];
        	
        	NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/login/login.php"];
        	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        	request.HTTPMethod = @"POST";
        	request.HTTPBody = [[NSString stringWithFormat:@"username=%@&password=%@", username, pwd] 
        	                                                  dataUsingEncoding:NSUTF8StringEncoding];
        	
        	[[[NSURLSession sharedSession] dataTaskWithRequest:request 
        	                                 completionHandler:^(NSData * _Nullable data, 
        	                                              NSURLResponse * _Nullable response, 
        	                                                    NSError * _Nullable error) {
            	
            	if (error == nil || data != nil) {
                	NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
                	if ([dict[@"userId"] intValue] > 0) {
        				[self saveUserLoginInfo];
                	}
            	}
        	}] resume];
        

    4、MD5 加密登录

    • MD5 加密具体实现代码见 GitHub 源码 QExtension

    • Objective-C

      • NSString+Hash.m

        	#import <CommonCrypto/CommonCrypto.h>
        
        	// MD5 散列函数
        	- (NSString *)md5String {
        
            	const char *str = self.UTF8String;
            	uint8_t buffer[CC_MD5_DIGEST_LENGTH];
        
            	CC_MD5(str, (CC_LONG)strlen(str), buffer);
        
            	return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
        	}
        
        	// HMAC 散列函数
        	- (NSString *)hmacMD5StringWithKey:(NSString *)key {
        	
            	const char *keyData = key.UTF8String;
            	const char *strData = self.UTF8String;
            	uint8_t buffer[CC_MD5_DIGEST_LENGTH];
            	
            	CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
            	
            	return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
        	}
        
        	// 时间戳散列函数
        	- (NSString *)timeMD5StringWithKey:(NSString *)key {
        		
            	NSString *hmacKey = key.md5String;
            	NSString *hmacStr = [self hmacMD5StringWithKey:hmacKey];
        
            	NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
            	fmt.dateFormat = @"yyyy-MM-ddHH:mm";
            	NSString *dateStr = [fmt stringFromDate:[NSDate date]];
        
            	hmacStr = [hmacStr stringByAppendingString:dateStr];
        
            	return [hmacStr hmacMD5StringWithKey:hmacKey];
        	}
        
        	// 助手方法
        	- (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
        		
            	NSMutableString *strM = [NSMutableString string];
            
            	for (int i = 0; i < length; i++) {
                	[strM appendFormat:@"%02x", bytes[i]];
            	}
            
            	return [strM copy];
        	}
        
      • 直接 md5 加密

        	// 用户名
        	NSString *username = self.usernameText.text;
        	
        	// 经 md5 加密的用户密码
        	NSString *pwd = [self.pwdText.text md5String];
        	
        	NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/login/login.php"];
        
      • md5 + 盐 加密

        	// “盐”,随机添加的字符串,要够长,够复杂
        	static NSString *salt = @"FUYGIUHIJKJHVBNOIUYUGVHJK@#$%^&))(&*^%W%$^%ukjsbcjcgvbk,jmhnrhjbjknklHDYCHGNKJB";
        	
        	// 用户名
        	NSString *username = self.usernameText.text;
        	
        	// 经 md5 加 盐 加密的用户密码
        	NSString *pwd = [[self.pwdText.text stringByAppendingString:salt] md5String];
        	
        	NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/login/login.php"];
        
      • md5 + HMAC 加密

        	// 用户名
        	NSString *username = self.usernameText.text;
        	
        	// 经 md5 加 HMAC 加密的用户密码
        	NSString *pwd = [[self.pwdText.text hmacMD5StringWithKey:@"qianqian"] md5String];
        	
        	NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/login/login.php"];
        
      • md5 + HMAC + 时间戳 加密

        	// 用户名
        	NSString *username = self.usernameText.text;
        	
        	// 经 md5 加 HMAC 加 时间戳 加密的用户密码
        	NSString *pwd = [self.pwdText.text timeMD5StringWithKey:@"qianqian"];
        	
        	NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/login/loginhmac.php"];
        
      • 登录代码段

        	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
        
        	request.HTTPMethod = @"POST";
        	request.HTTPBody = [[NSString stringWithFormat:@"username=%@&password=%@", username, pwd] 
        	                                                  dataUsingEncoding:NSUTF8StringEncoding];
        
        	[[[NSURLSession sharedSession] dataTaskWithRequest:request 
        	                                 completionHandler:^(NSData * _Nullable data, 
        	                                              NSURLResponse * _Nullable response, 
        	                                                    NSError * _Nullable error) {
            	
            	if (error == nil || data != nil) {
                	NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
                	if ([dict[@"userId"] intValue] > 0) {
        				[self saveUserLoginInfo];
                	}
            	}
        	}] resume];
        

    5、完整登录

    • Objective-C

      • AppDelegate.m

        	- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
            	
            	// 注册通知
            	/*
            		AppDelegate 中可以不移除
        		*/
        		
            	[[NSNotificationCenter defaultCenter] addObserver:self 
            	                                         selector:@selector(loginSuccess) 
            	                                             name:HQUserLoginSuccessedNotification 
            	                                           object:nil];
            	[[NSNotificationCenter defaultCenter] addObserver:self 
            	                                         selector:@selector(logout) 
            	                                             name:HQUserLogoutNotification 
            	                                           object:nil];
            	[[NSNotificationCenter defaultCenter] addObserver:self 
            	                                         selector:@selector(touchIDAuthentication) 
            	                                             name:HQTouchIDAuthenticationNotification 
            	                                           object:nil];
            	
            	// 直接用户登录
        		
        		// 如果成功,进入主页
            	[[NetworkTools sharedNetworkTools] userLoginWithTouchID:(BOOL)YES Failed:^{
            	
            		// 如果失败,进入登录页面
                	[self logout];
            	}];
            	
            	return YES;
        	}
        	
        	/// 登录成功
        	- (void)loginSuccess {
        	
        		// 显示主页面
            	[self switchStroyboard:@"Home"];
        	}
        	
        	/// 用户注销
        	- (void)logout {
        	
        		// 显示登录页面
            	[self switchStroyboard:@"Login"];
        	}
        	
        	/// 指纹验证
        	- (void)touchIDAuthentication {
            	[self switchStroyboard:@"TouchID"];
        	}
        	
        	/// 切换显示页面
        	- (void)switchStroyboard:(NSString *)sbName {
            	
            	UIStoryboard *sb = [UIStoryboard storyboardWithName:sbName bundle:nil];
            	self.window.rootViewController = sb.instantiateInitialViewController;
        	}
        
      • HomeViewController.m

        	#import "NetworkTools.h"
        	
        	/// 用户注销
        	- (IBAction)logout:(UIButton *)sender {
            	
            	[[NetworkTools sharedNetworkTools] userLogout];
        	}
        
      • LoginViewController.m

        	#import "NetworkTools.h"
        
        	@property (weak, nonatomic) IBOutlet UITextField *usernameText;
        	@property (weak, nonatomic) IBOutlet UITextField *pwdText;
        	@property (weak, nonatomic) IBOutlet UISwitch *savePwdSwitch;
        
        	- (void)viewDidLoad {
            	[super viewDidLoad];
            	
            	[self loadUserInfo];
        	}
        
        	/// 用户登录
        
        	- (IBAction)postLogin {
        
            	NetworkTools *tools = [NetworkTools sharedNetworkTools];
        
            	tools.username = self.usernameText.text;
            	tools.pwd = self.pwdText.text;
            	tools.isSavePwd = self.savePwdSwitch.isOn;
        
            	[tools userLoginWithTouchID:(BOOL)NO Failed:^{
                	UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" 
                	                                                                         message:@"用户名或密码错误" 
                	                                                                  preferredStyle:UIAlertControllerStyleAlert];
                	[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]];
                	[self presentViewController:alertController animated:YES completion:nil];
            	}];
        	}
        	
        	/// 加载用户信息
        	
        	- (void)loadUserInfo {
        		
            	self.usernameText.text = [NetworkTools sharedNetworkTools].username;
            	self.pwdText.text = [NetworkTools sharedNetworkTools].pwd;
        	}
        
        	/// 键盘回收
        
        	- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
            	[self.view endEditing:YES];
        	}
        
      • TouchIDViewController.m

        	#import "NetworkTools.h"
        
        	- (void)viewDidLoad {
            	[super viewDidLoad];
            	
            	[self touchIDAuthentication];
        	}
        
        	- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
            
            	[self touchIDAuthentication];
        	}
        
        	/// 指纹验证
        
        	- (void)touchIDAuthentication {
            
            	NetworkTools *tools = [NetworkTools sharedNetworkTools];
            
            	[tools touchIDAuthenticationFailed:^{
                	UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示" 
                	                                                                         message:@"指纹验证失败,请重试" 
                	                                                                  preferredStyle:UIAlertControllerStyleAlert];
                	[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleCancel handler:nil]];
                	[self presentViewController:alertController animated:YES completion:nil];
            	}];
        	}
        
      • NetworkTools.h

        	extern NSString * const HQUserLoginSuccessedNotification;
        	extern NSString * const HQUserLogoutNotification;
        	extern NSString * const HQTouchIDAuthenticationNotification;
            
        	@interface NetworkTools : NSObject
        
        	/// 用户名
        	@property (nonatomic, copy) NSString *username;
        
        	/// 用户口令
        	@property (nonatomic, copy) NSString *pwd;
        
        	/// 是否记住密码
        	@property (nonatomic, assign) BOOL isSavePwd;
            
        	/// 单例方法
        	+ (instancetype)sharedNetworkTools;
        
        	/// 用户登录
        	- (void)userLoginWithTouchID:(BOOL)touch Failed:(void (^)())failed;
        
        	/// 用户注销
        	- (void)userLogout;
        
        	/// 用户指纹验证
        	- (void)touchIDAuthenticationFailed:(void (^)())failed;
        
        	@end
        
      • NetworkTools.m

        	#import "NSString+TimePwd.h"
        	#import "SSKeychain.h"
        	#import <LocalAuthentication/LocalAuthentication.h>
        
        	// 定义通知字符串常量
        	NSString * const HQUserLoginSuccessedNotification = @"HMUserLoginSuccessedNotification";
        	NSString * const HQUserLogoutNotification = @"HMUserLogoutNotification";
        	NSString * const HQTouchIDAuthenticationNotification = @"HQTouchIDAuthenticationNotification";
            
        	@implementation NetworkTools
        
        	/**
         			单例创建中,使用 allocWithZone, copyWithZone ... 等等方法,会把所有创建第二个实例可能性全部堵死。
         		在真正开发中,有的时候,会需要额外创建一个副本。
         	*/
        	+ (instancetype)sharedNetworkTools {
            
            	static id instance;
            
            	static dispatch_once_t onceToken;
            	dispatch_once(&onceToken, ^{
                	instance = [[self alloc] init];
            	});
            	return instance;
        	}
        
        	- (instancetype)init {
            	self = [super init];
            	if (self) {
            	
            		// 第一次被实例化的时候,加载用户信息
            		[self loadUserLoginInfo];
            	}
            	return self;
        	}
        
        	/// 用户登录
        
        	/**
         		程序启动直接执行,如果登录成功,进入主界面。如果登录失败,进入登录页面。
         	*/
        	- (void)userLoginWithTouchID:(BOOL)touch Failed:(void (^)())failed {
            
            	NSString *username = self.username;
            	
            	// md5 + HMAC + 时间戳 加密
            	NSString *pwd = [self.pwd timeMD5StringWithKey:@"qianqian"];
            
            	NSURL *url = [NSURL URLWithString:@"http://192.168.88.200/login/loginhmac.php"];
            	NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
            
            	request.HTTPMethod = @"POST";
            	request.HTTPBody = [[NSString stringWithFormat:@"username=%@&password=%@", username, pwd] 
            	                                                  dataUsingEncoding:NSUTF8StringEncoding];
            
        		[[[NSURLSession sharedSession] dataTaskWithRequest:request 
            	                                 completionHandler:^(NSData * _Nullable data, 
            	                                              NSURLResponse * _Nullable response, 
            	                                                    NSError * _Nullable error) {
                
        			if (error == nil || data != nil) {
                    
        				NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
                    
        				dispatch_async(dispatch_get_main_queue(), ^{
                        
        					if ([dict[@"userId"] intValue] > 0) {
                        	
        						[self saveUserLoginInfo];
                        
        						if (touch == NO || [UIDevice currentDevice].systemVersion.floatValue < 8.0) {
                        	
        							// 发送登录成功通知
        							[[NSNotificationCenter defaultCenter] postNotificationName:HQUserLoginSuccessedNotification object:nil];
        						} else {
                        	
        							// 发送指纹验证通知
        							[[NSNotificationCenter defaultCenter] postNotificationName:HQTouchIDAuthenticationNotification object:nil];
        						}
        					} else {
        						if (failed != nil) {
                        	
        							// 执行失败回调
        							failed();
        						}
        					}
        				});
        			}
        		}] resume];
        	}
        
        	/// 用户注销
        
        	- (void)userLogout {
            
            	[SSKeychain deletePasswordForService:[NSBundle mainBundle].bundleIdentifier account:self.username];
            	
            	// 发送注销通知
            	[[NSNotificationCenter defaultCenter] postNotificationName:HQUserLogoutNotification object:nil];
        	}
        
        	/// 指纹验证
        
        	- (void)touchIDAuthenticationFailed:(void (^)())failed {
        
        		// 实例化本地身份验证上下文
            	LAContext *context= [[LAContext alloc] init];
        
            	// 判断是否支持指纹识别
            	if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:NULL]) {
        
            		// 发送登录成功通知
                	[[NSNotificationCenter defaultCenter] postNotificationName:HQUserLoginSuccessedNotification object:nil];
        
                	return;
            	}
            	
        		[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics 
            	        localizedReason:@"请验证已有指纹" 
            	                  reply:^(BOOL success, NSError * _Nullable error) {
                
        			dispatch_async(dispatch_get_main_queue(), ^{
                    
                  	// 输入指纹开始验证,异步执行
                   	if (success) {
        
                   		// 发送登录成功通知
                      	[[NSNotificationCenter defaultCenter] postNotificationName:HQUserLoginSuccessedNotification object:nil];        						
        				} else {
        					switch (error.code) {
        						case -1:
        							if (failed != nil) {
                                	
        								// 执行失败回调
        								failed();
        							}
        							break;
                                
        						case -2:
        						case -3:
        						case -4:
        						case -5:
        						case -6:
        						case -7:
        							// 发送注销通知
        							[[NSNotificationCenter defaultCenter] postNotificationName:HQUserLogoutNotification object:nil];
        							break;
                                
        						default:
        							break;
        					}
        				}
        			});
        		}];
        	}
        
        	/// 用户登录信息存储
        
        	- (void)saveUserLoginInfo {
            
            	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
            
            	[userDefaults setObject:self.username forKey:@"userNameKey"];
            	[userDefaults setBool:self.isSavePwd forKey:@"isSavePwdKey"];
            	[userDefaults synchronize];
            
            	if (self.isSavePwd) {
            	
            		// 将密码保存到钥匙串中
                	[SSKeychain setPassword:self.pwd forService:[NSBundle mainBundle].bundleIdentifier account:self.username];
            	} else {
                	self.pwd = nil;
                	[SSKeychain deletePasswordForService:[NSBundle mainBundle].bundleIdentifier account:self.username];
            	}
        	}
        
        	- (void)loadUserLoginInfo {
            
            	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
            	self.username = [userDefaults objectForKey:@"userNameKey"];
            	self.isSavePwd = [userDefaults boolForKey:@"isSavePwdKey"];
            
            	// 将密码从钥匙串中取出
            	self.pwd = [SSKeychain passwordForService:[NSBundle mainBundle].bundleIdentifier account:self.username];
        	}
        
        	@end
        
      • NSString+Hash.m

        	#import <CommonCrypto/CommonCrypto.h>
        
        	/// 时间戳散列函数
        
        	- (NSString *)timeMD5StringWithKey:(NSString *)key {												
            	NSString *hmacKey = key.md5String;
            	NSString *hmacStr = [self hmacMD5StringWithKey:hmacKey];
        
            	NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
            	fmt.dateFormat = @"yyyy-MM-ddHH:mm";
            	NSString *dateStr = [fmt stringFromDate:[NSDate date]];
        
            	hmacStr = [hmacStr stringByAppendingString:dateStr];
        
            	return [hmacStr hmacMD5StringWithKey:hmacKey];
        	}
        
        	/// HMAC 散列函数
        
        	- (NSString *)hmacMD5StringWithKey:(NSString *)key {
            	const char *keyData = key.UTF8String;
            	const char *strData = self.UTF8String;
            	uint8_t buffer[CC_MD5_DIGEST_LENGTH];
            
            	CCHmac(kCCHmacAlgMD5, keyData, strlen(keyData), strData, strlen(strData), buffer);
            
            	return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
        	}
        
        	/// 散列函数
        
        	- (NSString *)md5String {
            	const char *str = self.UTF8String;
            	uint8_t buffer[CC_MD5_DIGEST_LENGTH];
            
            	CC_MD5(str, (CC_LONG)strlen(str), buffer);
            
            	return [self stringFromBytes:buffer length:CC_MD5_DIGEST_LENGTH];
        	}
        
        	/// 助手方法
        
        	- (NSString *)stringFromBytes:(uint8_t *)bytes length:(int)length {
            	NSMutableString *strM = [NSMutableString string];
            
            	for (int i = 0; i < length; i++) {
                	[strM appendFormat:@"%02x", bytes[i]];
            	}
            
            	return [strM copy];
        	}
        

    6、保存用户信息

    • Objective-C

      • 明文保存

        	// 保存用户信息
        
        		NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];                 
        
        		[userDefaults setObject:self.usernameText.text forKey:@"userNameKey"];
        		[userDefaults setObject:self.pwdText.text forKey:@"userPwdKey"];
        
        		[userDefaults synchronize];
        
        	// 加载用户信息
        
        		NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        
        		self.usernameText.text = [userDefaults objectForKey:@"userNameKey"];                
        		self.pwdText.text = [userDefaults objectForKey:@"userPwdKey"];
        
      • base64 编码保存

        	// NSString+Base64.m
        
        		// 对 ASCII 编码的字符串进行 base64 编码
        		- (NSString *)base64Encode {
        
            		NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding];
            		return [data base64EncodedStringWithOptions:0];
        		}
        
        		// 对 base64 编码的字符串进行解码
        		- (NSString *)base64Decode {
        
            		NSData *data = [[NSData alloc] initWithBase64EncodedString:self options:0];
            		return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        		}
        
        	// 保存用户信息
        		
            	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
            	
            	[userDefaults setObject:self.usernameText.text forKey:@"userNameKey"];
            	
            	// 对密码进行 base64 编码
            	[userDefaults setObject:[self.pwdText.text base64Encode] forKey:@"userPwdKey"];
           	
            	[userDefaults synchronize];
        		
        	// 加载用户信息
        		
            	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
            	
            	self.usernameText.text = [userDefaults objectForKey:@"userNameKey"];
            	
            	// 对密码进行 base64 解码
            	self.pwdText.text = [[userDefaults objectForKey:@"userPwdKey"] base64Decode];
        
      • 钥匙串保存

        	// 添加第三方库文件
        	SSKeychain
        	
        	// 包含头文件
        	#import "SSKeychain.h"
        	
        	// 保存用户信息
        		
            	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
            	[userDefaults setObject:self.usernameText.text forKey:@"userNameKey"];
            	[userDefaults synchronize];
            	
            	// 将密码保存到钥匙串中
            	[SSKeychain setPassword:self.pwdText.text 
          	                 forService:[NSBundle mainBundle].bundleIdentifier 
          	                    account:self.usernameText.text];
        		
        	// 加载用户信息
        		
            	NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
            	self.usernameText.text = [userDefaults objectForKey:@"userNameKey"];
            	
            	// 将密码从钥匙串中取出
            	self.pwdText.text = [SSKeychain passwordForService:[NSBundle mainBundle].bundleIdentifier 
            	                                           account:self.usernameText.text];
        

    7、SSKeychain/SAMKeychain 的使用

    • GitHub 网址:https://github.com/soffes/SAMKeychain

    • SSKeychain/SAMKeychain 使用 ARC

    • Objective-C

      	// 添加第三方库文件
      	SSKeychain
      
      	// 包含头文件
      	#import "SSKeychain.h"
      
      	// 获取所有的账户信息
      
      		// 只有同一个开发者开发的应用程序,才能够互相看到账号
          	NSArray *allAccounts = [SSKeychain allAccounts];
         	
      	// 获取指定服务名的账户信息
      
          	NSArray *accounts = [SSKeychain accountsForService:[NSBundle mainBundle].bundleIdentifier];
         	
      	// 将密码保存到钥匙串中
      	/*
          	+ (BOOL)setPassword:(NSString *)password forService:(NSString *)serviceName account:(NSString *)account;
      
          	参数:
          		password   :密码明文
          		serviceName:服务名,可以随便写,建议使用 bundleId,应用程序的唯一标示,每一个上架的应用程序,都有一个唯一的 bundleId
          		account    :账户名(用户名)
       	*/
          
          	// 保存 NSString 格式的密码
      		[SSKeychain setPassword:self.pwdText.text 
      		             forService:[NSBundle mainBundle].bundleIdentifier 
      		                account:self.usernameText.text];    
      
          	NSData *pwdData = [self.pwdText.text dataUsingEncoding:NSUTF8StringEncoding];
          	
          	// 保存 NSData 格式的密码
          	[SSKeychain setPasswordData:pwdData 
          	                 forService:[NSBundle mainBundle].bundleIdentifier 
          	                    account:self.usernameText.text];          
      
      	// 将密码从钥匙串中取出
      
      		// 获取 NSString 格式的密码
          	self.pwdText.text = [SSKeychain passwordForService:[NSBundle mainBundle].bundleIdentifier 
          	                                           account:self.usernameText.text];
      
      		// 获取 NSData 格式的密码
          	NSData *pwdData1 = [SSKeychain passwordDataForService:[NSBundle mainBundle].bundleIdentifier 
          	                                              account:self.usernameText.text];   
      
      	// 将密码从钥匙串中删除
      
          	[SSKeychain deletePasswordForService:[NSBundle mainBundle].bundleIdentifier 
          	                             account:self.usernameText.text];
      
  • 相关阅读:
    α波、β波、θ波和δ波
    出体的真实性
    FreeBSD查看网络情况
    灰色理论预测模型
    主成分分析法
    常用OJ名字+地址(自用)
    2017 年“认证杯”数学中国数学建模网络挑战赛 比赛心得
    Codeforces Round #404 (Div. 2)(A.水,暴力,B,排序,贪心)
    hihoCoder #1053 : 居民迁移(贪心,二分搜索,google在线技术笔试模拟)
    Codeforces Round #408 (Div. 2)(A.水,B,模拟)
  • 原文地址:https://www.cnblogs.com/QianChia/p/5768614.html
Copyright © 2011-2022 走看看