#import "ViewController.h"
#import "NSString+Base64.h"
#import "NSString+Hash.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *usernameField;
@property (weak, nonatomic) IBOutlet UITextField *passwordField;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 读取保存的用户信息
[self loadUserInfo];
// NSLog(@"%@",[self base64EncodeWithStr:@"A"]);
// NSLog(@"%@",[self base64DecodeWithStr:@"QQ=="]);
}
/*
1. 不用管中间经过多少层加密
2. 加密方式都是跟后台商量好的,必须是一致
3. 工作中会有Api文档
*/
- (NSString *)passwordFromTime {
// 对key 加密
NSString *key = [@"itcast" md5String];
// 对 密码 加密
NSString *pwd = [self.passwordField.text hmacMD5StringWithKey:key];
// // 创建时间格式
// NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
//
// // 设置格式
// formatter.dateFormat = @"yyyy-MM-dd HH:mm";
//
// // 设置本地化
// formatter.locale = [NSLocale localeWithLocaleIdentifier:@"zh"];
// 时间字符串
// NSString *time = [formatter stringFromDate:[NSDate date]];
//
// NSDate *date=[NSDate date];
//
// NSLog(@"%@----%@",date,time);
// 时间有效期是两分钟,如果两分钟都没有登录成功,早就超时了
// 取出服务器的时间
NSURL *url = [NSURL URLWithString:@"http://localhost/hmackey.php"];
// 使用同步来获取对应的数据
NSData *data = [NSData dataWithContentsOfURL:url];
if (data == nil) {
NSLog(@"没有网络或者服务器没响应");
return nil;
}
// 解析json
id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
// NSLog(@"%@",result);
// 把第一次加密的结果 拼上时间字符串
pwd = [pwd stringByAppendingString:result[@"key"]];
// 再加密
pwd = [pwd hmacMD5StringWithKey:key];
return pwd;
}
- (IBAction)login:(id)sender {
// 开始显示指示器(MB)
// 拼接POST参数
// md5 两次也不安全
// 加盐 对 zhang 加密 (现在使用也比较少)
// 在本还存在base64
// 在传输中保存的是md5
// 39a6e768e13864f21cbff0604500d280 每次加密结果都是一样的
// NSString *key = @"itcast";
//
// NSString *pwd = [[self.passwordField.text stringByAppendingString:key] hmacMD5StringWithKey:key];
// NSLog(@"%@",params);
// 在真实开发中,项目名或者文件夹尽量不要使用中文
NSString *URLString = [NSString stringWithFormat:@"http://localhost/loginhmac.php"];
// NSURL 在工作中,不止是php为后缀,还有可能是其他的,jsp,asp,.do,.action,不管什么后缀,在我们眼里都是一样的
NSURL *url = [NSURL URLWithString:URLString];
// NSURLRequest
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:15];
// 请求默认是GET,如果要使用POST必须是可变的请求
// 设置POST请求
[request setHTTPMethod:@"POST"];
//为什么在这里加密?预防网络拦截? 登录需要一个端口,只能在这个端口输入正确密码才能进入账户,在密码传输到服务器的过程中要对正确密码进行加密,不然密码被拦截了就暴露了。
NSString *pwd = [self passwordFromTime];
NSLog(@"%@",pwd);
NSString *params = [NSString stringWithFormat:@"username=%@&password=%@",self.usernameField.text,pwd];
// 设置POST参数,不需要百分号转码
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];
// NSURLConnection
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
// NSLog(@"%@",response);
id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSLog(@"%@",result);
// 如果登录成功,保存用户信息
// 判断返回结果是否有userId,如果有登录成功,如果没有,登录失败
if (result[@"userId"]) {
[self saveUserInfo];
}
}];
}
#define CZUserName @"CZUserName"
#define CZPassword @"CZPassword"
// 保存用户信息
- (void)saveUserInfo {
// 使用偏好设置保存用户信息
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
// NSLog(@"%@",NSHomeDirectory());
// 保存用户名
[defaults setObject:self.usernameField.text forKey:CZUserName];
// 保存密码
[defaults setObject:[self.passwordField.text base64Encode] forKey:CZPassword];
// 同步 iOS8 以后不需要调用同步就可以,但是如果需要适配iOS7还是需要调用
// [defaults synchronize];
}
// 读取用户信息
- (void)loadUserInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
self.usernameField.text = [defaults objectForKey:CZUserName];
self.passwordField.text = [[defaults objectForKey:CZPassword] base64Decode];
}
@end
网络:hmac 与服务器时间
最新推荐文章于 2024-04-10 08:00:00 发布