iOS - Sign up/in 注册/登录

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 1、Sign up/in1.1 用户登录安全原则不能在网络上传输用户隐私数据的明文。不能在本地和服务器上存储用户隐私数据的明文。1.2 用户登录流程登录成功之后,应该跳转视图控制器到主页。

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];
目录
相关文章
|
iOS开发
iOS 分享 第三方登录 Twitter 注册应用以及读写权限
iOS 分享 第三方登录 Twitter 注册应用以及读写权限
440 0
|
4月前
|
开发工具 iOS开发 计算机视觉
|
6月前
|
Android开发 数据安全/隐私保护 iOS开发
ios和安卓测试包发布网站http://fir.im的注册与常用功能
ios和安卓测试包发布网站http://fir.im的注册与常用功能
272 0
ios和安卓测试包发布网站http://fir.im的注册与常用功能
|
网络协议 Shell 网络安全
iOS 逆向编程(九 - 1)通过 USB 连接登录 iPhone 以及端口映射
iOS 逆向编程(九 - 1)通过 USB 连接登录 iPhone 以及端口映射
300 0
|
存储 网络安全 数据安全/隐私保护
iOS 逆向编程(七)客户端(手机)免密认证登录
iOS 逆向编程(七)客户端(手机)免密认证登录
130 0
|
存储 安全 网络协议
iOS 逆向编程(五)通过 (OpenSSH) Wifi 远程连接登录 iPhone
iOS 逆向编程(五)通过 (OpenSSH) Wifi 远程连接登录 iPhone
375 0
|
iOS开发
iOS开发 - 千万不要把通知注册写在viewWillAppera里面
iOS开发 - 千万不要把通知注册写在viewWillAppera里面
98 0
|
存储 安全 API
解决 iOS 15 上 APP 莫名其妙地退出登录
在 iOS 15 公开推出后, 我们开始从用户端收到反馈报告:在打开我们的应用程序(Cookpad) 时他们被莫名其妙的反复退出到登录页。非常令人惊讶的是,这并不是我们在测试 iOS 15 beta 版的时候发现的问题。
172 0
|
存储 安全 测试技术
iOS登录流程优化:冷启动时token过期之前自动登录
iOS登录流程优化:冷启动时token过期之前自动登录
655 0
iOS登录流程优化:冷启动时token过期之前自动登录
|
开发工具 iOS开发
ios授权登录sdk分享(不包含支付功能)
说明:   为了解决开发者在ios中使用支付宝授权接口产品上架问题,所以推出授权登录相关sdk(不包含支付功能) 如果商户有使用到支付宝登录授权功能接口,可以参考使用。   ios SDK:AFAuthSDK.
685 0