03-GET,POST,用户登录

2017-08-27  本文已影响514人  AlanGe

一、HTTP常用方法

1、GET 请求

2、POST 请求

3、GET 缓存

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    NSURL *url = [NSURL URLWithString:@"[http://localhost/itcast/images/head1.png](http://localhost/itcast/images/head1.png)"];

//    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:15.0];

    // 传递 etag
    if (self.etag.length > 0) {
        [request setValue:self.etag forHTTPHeaderField:@"If-None-Match"];
    }

    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

        NSLog(@"%@,%zd",response,data.length);

        // 类型转换(在oc中,如果将父类转换成子类需要强制转换)
        NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;

        // 获取并记录 etag,区分大小写
        self.etag = httpResponse.allHeaderFields[@"Etag"];

        // 判断响应状态码是否是 304 Not Modified
        if (httpResponse.statusCode == 304) {

            NSLog(@"加载本地数据");

            // 如果是,使用本地缓存
            // 根据请求获得被缓存的响应
            NSCachedURLResponse *cacheResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];

            // 拿到缓存的数据
            data = cacheResponse.data;
        }

        NSLog(@"etag = %@",self.etag);

        self.iconView.image = [UIImage imageWithData:data];
    }];
}

4、NSURLCache--设置缓存

// 设置网络缓存
// 4M 的内存缓存
// 20M 的磁盘缓存
// diskPath:缓存路径   nil:表示使用系统默认的缓存路径:沙盒/Library/Caches
NSURLCache *cache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:@"pkxing"];
// 设置全局缓存
[NSURLCache setSharedURLCache:cache];
# AFNetworking的作者Mattt说:无数开发者尝试自己做一个简陋而脆弱的系统来实现网络缓存功能,殊不知 NSURLCache 只要两行代码就能搞定且好上100倍。

二、用户登录

1、GET登录

- (void)getLogin{
       // 创建url
/**
     url扩展:
     1、login.php 负责登录的脚本,提示:上课使用的是 php,而工作中不一定,可能是.jsp,asp,aspx...取决于后台,后台提供什么,客户端就用什么。
     2、‘?’ 表示接参数
     3、参数格式:变量名=值
     4、‘&’ 多个参数拼接
     */
    NSString urlStr = [NSString stringWithFormat:@"http://localhost/login.php?username=%@&password=%@",self.userName,self.password];
    // 如果url 字符串中,包含中文或空格等特殊字符,需要添加百分号转义
    urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url = [NSURL URLWithString:urlStr];
    // 创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    // 请求的默认方法就是 GET
        // GET 效率高,使用频率高的访问  建议是用GET! POST一般用来发送订单,个人隐私数据,上传文件....
    NSLog(@"%@",request.HTTPMethod);
    // 发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        NSLog(@"%@,%@",response,dict);
    }];
}
NSString urlStr = [NSString stringWithFormat:@"http://localhost/login.php?username=% @&password=%@",self.userName,self.password];

// 如果url 字符串中,包含中文或空格等特殊字符,需要添加百分号转义
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

2、POST登录

- (void)postLogin{
    // 创建url,不需要添加百分号转义(内部已经实现)
    NSURL *url = [NSURL URLWithString:@"http://localhost/login.php"];
    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    // 设置请求方法为 POST
    request.HTTPMethod = @"POST";
    // 设置请求体二进制数据
    NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@",self.userName,self.password];
    //    request.HTTPBody = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
    request.HTTPBodyStream = [[NSInputStream alloc] initWithData:[bodyStr dataUsingEncoding:NSUTF8StringEncoding]];
    // 发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        NSLog(@"%@,%@",response,dict);
    }];
}

3、GET和POST 请求对比

三、模拟登录

1、搭建界面

2、保存登录信息

#define HMUsernameKey @"HMUsernameKey"
#define HMPasswordKey @"HMPasswordKey"
- (void)saveUserInfo{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:self.nameField.text forKey:HMUsernameKey];
    [defaults setObject:self.passField.text forKey:HMPasswordKey];
}
- (void)loadUserInfo{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    self.nameField.text = [defaults valueForKey:HMUsernameKey];
    self.passField.text = [defaults valueForKey:HMPasswordKey];
}

四、Base64

1、简介

参考网站:http://zh.wikipedia.org/wiki/Base64

2、原理

参考文章:http://www.cnblogs.com/hongru/archive/2012/01/14/2321397.html

注:如果被编码字符长度不是3的倍数的时候,则都用0代替,对应的输出字符为=

ABC
01000001 01000010 01000011
010000 010100 001001 000011
16 20 9 3
QUJD

AB
01000001 01000010
010000 010100 001000
16 20 8
QUI=

A
010000 010000
16 16
QQ==

Base64对照表

3、终端命令

# 将 abc.png 进行 base64编码,生成 xxx.txt 文件
$ base64 abc.png -o xxx.txt // -o 表示输出

# 将 xxx.txt 解码生成1.png
$ base64 -D xxx.txt -o 1.png // -D 表示 decoder 解码

# 将字符串 ABC 进行 base64 编码
$ echo -n ABC | base64

# 将字符串 QUJD 解码
$ echo -n QUJD | base64 -D

4、Base64代码实现

#pragma mark - Base64
// 编码:A => QQ==
-(NSString *)base64Encode:(NSString *)string{
    // 1.将字符串转换成二进制数据
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    // 2.利用 ios7.0的方法,直接 base64 编码
    return [data base64EncodedStringWithOptions:0];
}
// 解码:QQ== => A
- (NSString *)base64Decode:(NSString *)string {
    // 1.将 base64编码后的字符串,解码成二进制数据
    // 这里不能使用注释掉的方法转换成二进制,因为 string 就是已经编码过的字符串
    //    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [[NSData alloc] initWithBase64EncodedString:string options:0];
    // 2.返回解码的字符串
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}

五、MD5加密

1、MD5是什么

Message Digest Algorithm MD5(中文名为消息摘要算法第五版)是计算机安全领域广泛使用的一种散列函数(也叫Hash函数),用以提供消息的完整性保护。其核心思想是从给定的数据中提取特征码,不容产生重复。加密后的字符串通常被称为指纹或消息摘要。 32位

2、MD5算法特点

3、MD5的作用

4、MD5加密实现

NSString *password = self.passField.text.md5String; // 执行一次 MD5
NSString *password = self.passField.text.md5String.md5String; // 执行两次 MD5
// 准备盐
static NSString *salt = @"fadsfdbvcxweioa4321asfFAFA321DSFASDF%$%$^$^$$#@23123124{}{4";
NSString *password = [self.passField.text stringByAppendingString:salt].md5String;

温馨提示:‘盐’在现实生活中是佐料,就是给密码加点料,salt要够咸(复杂点的字符串)。

5、生成带时间戳的密码

使用时间戳,目前使用非常广泛

- (NSString *)timePassword{

    // 1.设置密钥 key

    NSString *key = @"itheima".md5String;

    // 2.使用密钥key对密码进行HMac

    NSString *pwd = [self.passField.text hmacMD5StringWithKey:key];

    NSLog(@"key = %@",key);

    // 3.获得当前的系统时间

    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];

    // 指定时区,真机通常需要指定时区

    fmt.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"zh"];

    // 设置时间格式

    fmt.dateFormat = @"yyyy-MM-dd HH:mm";

    // 格式化当前时间

    NSString *dateStr = [fmt stringFromDate:[NSDate date]];

    

    // 4.用密码 + 时间 生成 密码

    pwd = [pwd stringByAppendingString:dateStr];

    // 5.返回 hmac 结果

    return [pwd hmacMD5StringWithKey:key];

}

NSString *password = [self timePassword];
- (NSString *)timePassword{
    // 1.设置密钥 key
    NSString *key = @"itheima".md5String;
    // 2.对密钥key对密码进行HMac
    NSString *pwd = [self.passField.text hmacMD5StringWithKey:key];
    
    // 3.获得当前服务器的系统时间
    NSURL *url = [NSURL URLWithString:@"http://localhost/hmackey.php"];
    // 使用同步获取时间(注意:这里要使用同步,确定先获得服务器的时间,后面的代码才能执行)
    NSData *timeData = [NSData dataWithContentsOfURL:url];
    // 反序列化取出时间
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:timeData options:0 error:NULL];
    NSString *dateStr = dict[@"key"];

    // 4.用密码 + 时间 生成 密码
    pwd = [pwd stringByAppendingString:dateStr];
    // 5.返回 hmac 结果
    return [pwd hmacMD5StringWithKey:key];
}

6、其他

破解网站:http://www.cmd5.com

六、钥匙串访问

1、钥匙串简介

2、代码实现

- (void)saveUserInfo{

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setValue:self.nameField.text forKey:HMUsernameKey];

    // 保存到密码到钥匙串

    /**
     参数:
     1.密码‘明文’,加密工作苹果做了,使用的是 AES 256 算法
     2.服务名,可以随便写,建议使用bundleId
     3.帐号,用户名。因为钥匙串访问中,可以保存很多帐号,很多app的密码
     */

    NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;

    [SSKeychain setPassword:self.passField.text forService:bundleId account:self.nameField.text];
}
- (void)loadUserInfo{
   NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
   self.nameField.text = [defaults valueForKey:HMUsernameKey];
   
    // 从钥匙串中获得密码
    NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
   self.passField.text = [SSKeychain passwordForService:bundleId account:self.nameField.text];
}

七、重构登录代码

// 登录成功通知
#define HMLoginSuccessNotification @"HMLoginSuccessNotification"

@interface HMNetworkTools : NSObject
/**
 *  全局访问点,用来获取单列对象
 */
+(instancetype)sharedTools;
/**
 *  登录
 */
- (void)loginFailed:(void (^)())failed;

/**
 *  用户名
 */
@property(nonatomic,copy) NSString *username;
/**
 *  密码
 */
@property(nonatomic,copy) NSString *pwd;
@end

@implementation HMNetworkTools
/**
 *  全局访问点,用来获取单列对象
 */
+(instancetype)sharedTools{
    static id instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (instancetype)init {
    if (self = [super init]) {
        [self loadUserInfo];
    }
    return self;
}

/**
 *  登录
 */
- (void)loginFailed:(void (^)())failed{
    NSAssert(failed != nil, @"必须传入回调");
    // 判断用户名或密码是否有值
    if(!(self.username.length > 0 && self.pwd.length > 0)){
        failed();
        return;
    }
    NSString *password = [self timePassword];
    NSLog(@"发送的密码=%@",password);
    // 创建url
    NSURL *url = [NSURL URLWithString:@"http://localhost/loginhmac.php"];
    // 创建请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url ];
    // 设置请求方法为 POST
    request.HTTPMethod = @"POST";
    // 设置请求体二进制数据
    NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@",_username,password];
    request.HTTPBodyStream = [[NSInputStream alloc] initWithData:[bodyStr dataUsingEncoding:NSUTF8StringEncoding]];
    // 发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        if([dict[@"userId"] intValue] > 0) {
            // 登录成功,保存用户信息
            [self saveUserInfo];
            // 发送通知
            [[NSNotificationCenter defaultCenter] postNotificationName:HMLoginSuccessNotification object:@"Main"];
        } else {
             failed();
        }
    }];
}


#pragma mark - 私有方法

/**
 *  生成带时间戳的密码
 */
- (NSString *)timePassword{
    // 1.设置密钥 key
    NSString *key = @"itheima".md5String;
    // 2.对密钥key对密码进行HMac
    NSString *pwd = [self.pwd hmacMD5StringWithKey:key];
    
    // 3.获得当前服务器的系统时间
    NSURL *url = [NSURL URLWithString:@"http://localhost/hmackey.php"];
    // 使用同步获取时间
    NSData *timeData = [NSData dataWithContentsOfURL:url];
    // 反序列化取出时间
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:timeData options:0 error:NULL];
    NSString *dateStr = dict[@"key"];
    // 4.用密码 + 时间 生成 密码
    pwd = [pwd stringByAppendingString:dateStr];
    // 5.返回 hmac 结果
    return [pwd hmacMD5StringWithKey:key];
}


#pragma mark - 保存和加载用户信息
#define HMUsernameKey @"HMUsernameKey"
#define HMPasswordKey @"HMPasswordKey"
/**
 *  保存用户登录信息
 */
- (void)saveUserInfo{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:self.username forKey:HMUsernameKey];
    
    NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
    [SSKeychain setPassword:self.pwd forService:bundleId account:self.username];
}

/**
 *  加载用户登录信息
 */
- (void)loadUserInfo{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    self.username = [defaults valueForKey:HMUsernameKey];
    // 从钥匙串中获得密码
    NSString *bundleId = [NSBundle mainBundle].bundleIdentifier;
    self.pwd = [SSKeychain passwordForService:bundleId account:self.username];
}
上一篇 下一篇

猜你喜欢

热点阅读