首页 > 代码库 > 客户端session问题总结

客户端session问题总结

对于客户端来说,session即为我们拿到的cookie,cookie能让客户端保持http的状态信息。那么cookie是怎么来的?cookie是怎么管理的?cookie是怎么做增删改的?通过项目和对一些文章的阅读,主要阐述一下上面几个问题。

在讲这几个问题之前先说下服务器和客户端如何获取sessionid和sessionid如何传输的。

当服务器第一次接收到客户端请求时会生成一块session空间用于创建session对象,同时生成sessionid通过响应头的set-cookie:"JSESSIONID=..."发送给客户端,需要注意的是在接下来同一个会话第二次第三次响应头中不再出现set-cookie。为了维持当前会话,客户端在接下来的每次请求都需要在请求头中设置该cookie,服务器通过cookie信息中的JSESSIONID就能找到当前会话的sessionid。

 

cookie是用来维持服务端会话状态的,由服务端写入,在后续请求中由服务端读取。当你访问一个网站时,NSURLRequest都会帮你主动记录下来你访问的站点设置的Cookie,如果 Cookie 存在的话,会把这些信息放在 NSHTTPCookieStorage 容器中共享,当你下次再访问这个站点时,NSURLRequest会拿着上次保存下来了的Cookie继续去请求。cookie就是通过NSHTTPCookieStorage进行管理的,NSHTTPCookieStorage 实现了一个管理cookie的单例对象,每个Cookie都是NSHTTPCookie类的实例,在OS X中,Cookie在所有应用之间共享并在不同进程之间保持同步,Session Cookie(一个isSessionOnly方法返回YES的Cookie)只能在单一进程中使用,在iOS中,单个应用共享。每当客户端访问一个新的服务器,NSHTTPCookieStorage中就会生成一个新的NSHTTPCookie类,存储着当前服务器的session信息。当客户端向这个服务器再次发起请求时,客户端会自动带着当前服务器的session信息请求。

 

我现在做的项目,由于request对象被封装了,导致我无法给请求头手动设置Cookie,那么不去设置Cookie服务器是否还能维持当前会话?答案是可以的,经过我的实测,发现当你访问一个网站时,不管你愿意或者不愿意,NSURLRequest都会帮你主动记录下来你访问的站点设置的 cookie,而且很负责任的,当你下次再访问这个站点时,NSURLRequest会拿着上次保存下来了的cookie继续去请求。

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [cookieStorage cookies]) {
   NSLog(@"%@", cookie);
}

通过管理NSHTTPCookieStorage对象,也可以实现与服务器之间的会话状态改变。

cookie删除:

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
  NSArray *_tmpArray = [NSArray arrayWithArray:[cookieStorage cookies]];
  for (id obj in _tmpArray) {
    [cookieJar deleteCookie:obj];
  }

cookie设置:

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"username" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"rainbird" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"cnrainbird.com" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"cnrainbird.com" forKey:NSHTTPCookieOriginURL];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
 
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];

NSHttpCookiesStorage是一个单例,管理所有的Cookie,每个Cookie都是一个NSHTTPCookie的实例,所有应用的cookies都被保存在这个NSHTTPCookieStorage的单例中,并且跨进程同步。  但为了安全,每个应用都有自己的沙盒,A应用的cookie是不能被B应用访问的。

 通过NSHTTPCookieStorage可读取/修改cookie接收策略,默认为NSHTTPCookieAcceptPolicyAlways.

- (NSHTTPCookieAcceptPolicy)cookieAcceptPolicy;
- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)aPolicy.

一共有三种cookie accept policy,

typedef enum {
   NSHTTPCookieAcceptPolicyAlways,
   NSHTTPCookieAcceptPolicyNever,
   NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
} NSHTTPCookieAcceptPolicy;

NSHTTPCookieAcceptPolicyAlways:接收所有cookie,默认策略.
NSHTTPCookieAcceptPolicyNever: 拒绝所有cookie
NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只接收main document domain中的cookie.

 

相关通知

NSHTTPCookieManagerCookiesChangedNotification
当NSHTTPCookieStorage实例中的cookies变化时发出此通知。

NSHTTPCookieManagerAcceptPolicyChangedNotification
当NSHTTPCookieStorage实例的cookie acceptance policy变化时发出此通知。

 

参考文章: iOS中Cookie介绍

 

客户端session问题总结