相同 URL 但不同用户的 NSHTTPCookieStorage
NSHTTPCookieStorage for same URL but different users
可能这是一个愚蠢的问题,但我想为相同的 url 存储 cookie,但对于用户名不同。如何使用 NSHTTPCookieStorage 实现这一点?这就是我存储来自响应的 cookie 的方式。
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSDictionary *headerFields = [httpResponse allHeaderFields];
NSArray* cookies = [NSHTTPCookie
cookiesWithResponseHeaderFields:headerFields
forURL:[NSURL URLWithString:@""]];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
NSString *urlString = ...;
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:[NSURL URLWithString:urlString] mainDocumentURL:nil];
如果我没理解错的话,您希望为不同的用户设置不同的 cookie 集。如果是这样,那么您应该:
创建您自己的自定义 cookie 存储 class(可能只是一个字典,以 URL 作为键,一个 cookie 数组作为值)并在那里存储 cookie除了使用 sharedHTTPCookieStorage
对象。
当您更改用户时,擦除共享 cookie 存储并从新用户的 cookie jar 中复制 cookie(或者有选择地从共享 jar 中删除该用户创建的每个 cookie)。
如果我误解了你,而你出于某种原因想要在共享 cookie 存储之外存储一个特定的 cookie:
根据配置创建一个 NSURLSession 对象,使用 nil cookie jar(禁用自动 cookie 存储)。
像上面那样将 cookie 存储到 cookie 罐中(可能是也可能不是共享的 cookie 罐),但省去您不想存储的那些。
编写一个方法,将 cookie 罐中的 cookie 添加到 NSURLRequest 对象。
永远记得在使用 URL 请求对象创建任务之前调用该方法。
当然,这一切都假定 NSURLSession。我认为没有办法通过 NSURLConnection 来控制 cookie 存储。所有 cookie 都存储在 cookie 罐中,期间,AFAIK。
您可以使用 sharedCookieStorage(forGroupContainerIdentifier:)
.
为同一个 URL 拥有单独的 cookie 存储(即多个用户)
您可以使用该方法获得一个通用的cookie存储,并在URLSession
中使用它。
示例:
相同 URL 但不同用户的 NSHTTPCookieStorage
let configuration = URLSessionConfiguration.default.copy() as! URLSessionConfiguration
configuration.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: UUID().uuidString)
configuration.httpCookieStorage?.cookieAcceptPolicy = .always
let sessionForCurrentUser = URLSession(configuration: configuration)
let task = sessionForCurrentUser.dataTask(with: URL(string: "https://foo.com/feature")!)
// ...
因此,如果您想支持多个用户,请为每个用户创建一个公共组标识符。
如果应用程序由来宾用户启动,则您需要 "upgrade" 在用户登录时存储 cookie。类似于:
// Upgrade from Guest user to Paid user
let guestCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: guestId)
let userCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: user.uniqueIdentifier)
for cookie in guestCookieStorage.cookies ?? [] {
userCookieStorage.setCookie(cookie)
}
@interface NSHTTPCookieStorage (ApplePrivateHeader)
-(id)_initWithIdentifier:(id)arg1 private:(BOOL)arg2;
@end
@interface User()
@property (nonatomic, strong) NSHTTPCookieStorage *myHTTPCookieStorage;
@end
@implementation User
-(instancetype)init
{
self = [super init];
if (self) {
//the [NSHTTPCookieStorage init] will generate a instance with no inner `NSHTTPCookieStorageInternal`, so.
_myHTTPCookieStorage = [[NSHTTPCookieStorage alloc] _initWithIdentifier: @"user_id_xxx" private:0];
_myHTTPCookieStorage.cookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways;
}
return self;
}
-(void)httpTask{
NSURLSessionConfiguration *c =[NSURLSessionConfiguration ephemeralSessionConfiguration];
c.HTTPCookieStorage = _myHTTPCookieStorage;
[[[NSURLSession sessionWithConfiguration: c] dataTaskWithRequest:request completionHandler:nil] resume];
}
// load from file
-(void)(id)initWithCoder:(NSCoder *)aDecoder{
NSArray<NSHTTPCookie*> *cookies = [aDecoder decodeObjectForKey:@"cookies"];
for (NSHTTPCookie *cookie in cookies) {
[_myHTTPCookieStorage setCookie: cookie];
}
}
//save to file
- (void)encodeWithCoder:(NSCoder *)aCoder
[aCoder encodeObject:_myHTTPCookieStorage.cookies forKey: @"cookies"];
}
@end
可能这是一个愚蠢的问题,但我想为相同的 url 存储 cookie,但对于用户名不同。如何使用 NSHTTPCookieStorage 实现这一点?这就是我存储来自响应的 cookie 的方式。
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
NSDictionary *headerFields = [httpResponse allHeaderFields];
NSArray* cookies = [NSHTTPCookie
cookiesWithResponseHeaderFields:headerFields
forURL:[NSURL URLWithString:@""]];
for (NSHTTPCookie *cookie in cookies) {
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
}
NSString *urlString = ...;
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:[NSURL URLWithString:urlString] mainDocumentURL:nil];
如果我没理解错的话,您希望为不同的用户设置不同的 cookie 集。如果是这样,那么您应该:
创建您自己的自定义 cookie 存储 class(可能只是一个字典,以 URL 作为键,一个 cookie 数组作为值)并在那里存储 cookie除了使用
sharedHTTPCookieStorage
对象。当您更改用户时,擦除共享 cookie 存储并从新用户的 cookie jar 中复制 cookie(或者有选择地从共享 jar 中删除该用户创建的每个 cookie)。
如果我误解了你,而你出于某种原因想要在共享 cookie 存储之外存储一个特定的 cookie:
根据配置创建一个 NSURLSession 对象,使用 nil cookie jar(禁用自动 cookie 存储)。
像上面那样将 cookie 存储到 cookie 罐中(可能是也可能不是共享的 cookie 罐),但省去您不想存储的那些。
编写一个方法,将 cookie 罐中的 cookie 添加到 NSURLRequest 对象。
永远记得在使用 URL 请求对象创建任务之前调用该方法。
当然,这一切都假定 NSURLSession。我认为没有办法通过 NSURLConnection 来控制 cookie 存储。所有 cookie 都存储在 cookie 罐中,期间,AFAIK。
您可以使用 sharedCookieStorage(forGroupContainerIdentifier:)
.
您可以使用该方法获得一个通用的cookie存储,并在URLSession
中使用它。
示例:
相同 URL 但不同用户的 NSHTTPCookieStorage
let configuration = URLSessionConfiguration.default.copy() as! URLSessionConfiguration
configuration.httpCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: UUID().uuidString)
configuration.httpCookieStorage?.cookieAcceptPolicy = .always
let sessionForCurrentUser = URLSession(configuration: configuration)
let task = sessionForCurrentUser.dataTask(with: URL(string: "https://foo.com/feature")!)
// ...
因此,如果您想支持多个用户,请为每个用户创建一个公共组标识符。
如果应用程序由来宾用户启动,则您需要 "upgrade" 在用户登录时存储 cookie。类似于:
// Upgrade from Guest user to Paid user
let guestCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: guestId)
let userCookieStorage = HTTPCookieStorage.sharedCookieStorage(forGroupContainerIdentifier: user.uniqueIdentifier)
for cookie in guestCookieStorage.cookies ?? [] {
userCookieStorage.setCookie(cookie)
}
@interface NSHTTPCookieStorage (ApplePrivateHeader)
-(id)_initWithIdentifier:(id)arg1 private:(BOOL)arg2;
@end
@interface User()
@property (nonatomic, strong) NSHTTPCookieStorage *myHTTPCookieStorage;
@end
@implementation User
-(instancetype)init
{
self = [super init];
if (self) {
//the [NSHTTPCookieStorage init] will generate a instance with no inner `NSHTTPCookieStorageInternal`, so.
_myHTTPCookieStorage = [[NSHTTPCookieStorage alloc] _initWithIdentifier: @"user_id_xxx" private:0];
_myHTTPCookieStorage.cookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways;
}
return self;
}
-(void)httpTask{
NSURLSessionConfiguration *c =[NSURLSessionConfiguration ephemeralSessionConfiguration];
c.HTTPCookieStorage = _myHTTPCookieStorage;
[[[NSURLSession sessionWithConfiguration: c] dataTaskWithRequest:request completionHandler:nil] resume];
}
// load from file
-(void)(id)initWithCoder:(NSCoder *)aDecoder{
NSArray<NSHTTPCookie*> *cookies = [aDecoder decodeObjectForKey:@"cookies"];
for (NSHTTPCookie *cookie in cookies) {
[_myHTTPCookieStorage setCookie: cookie];
}
}
//save to file
- (void)encodeWithCoder:(NSCoder *)aCoder
[aCoder encodeObject:_myHTTPCookieStorage.cookies forKey: @"cookies"];
}
@end