target-c очистить NSURLCredential - NSURLCredentialPersistenceForSession
Я использую NSURLCredentials
в этом методе:
-(void)UserLogin:(NSString *)user andPassWordExists:(NSString *)password completionHandler:(void (^)(NSArray *resultsObject, NSError *error))completionHandler
{
NSURL *url = [NSURL URLWithString:kIP];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
NSURLCredential *credential = [NSURLCredential
credentialWithUser:user
password:password
persistence:NSURLCredentialPersistenceForSession];
[operation setCredential:credential];
[[NSOperationQueue mainQueue] addOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (completionHandler) {
completionHandler(responseObject, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
[operation start];
}
И теперь я хочу очистить NSURLCredentials в методе выхода из системы, например:
-(void)logout
{
//Clear NSURLCredentialPersistenceForSession
}
Как бы я поступил так? Должен ли я сбросить NSURLCredentials или там, чтобы очистить их?
ОБНОВИТЬ
Я нашел это решение:
NSURLCredentialStorage *credentialStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *credentialsDicationary = [credentialStorage allCredentials];
for (NSURLProtectionSpace *space in [credentialsDicationary allKeys]) {
NSDictionary *spaceDictionary = [credentialsDicationary objectForKey:space];
for (id userName in [spaceDictionary allKeys]) {
NSURLCredential *credential = [spaceDictionary objectForKey:userName];
[credentialStorage removeCredential:credential forProtectionSpace:space];
}
}
Это лучший способ? У меня есть только 1 сохраненные учетные данные. Также этот код дает мне предупреждение в этой строке:
NSURLCredential *credential = [spaceDictionary objectForKey:userName];
и вот предупреждение... как мне убрать это предупреждение?
/Users/jsuske/Documents/SSiPad(Device Only)ios7/SchedulingiPadApplication/ViewControllers/LHLoginController.m:496:73: Local declaration of 'userName' hides instance variable
ОБНОВИТЬ
Итак, у меня есть 3 метода:UserLogin, Login и LogoutButtonPressed
UserLogin: я использую AFNetworking для подключения к URL-адресу, прошедшему проверку подлинности Windows, с использованием NSURLCredential, как показано выше:
-(void)UserLogin:(NSString *)user andPassWordExists:(NSString *)password completionHandler:(void (^)(NSArray *resultsObject, NSError *error))completionHandler
{
NSURL *url = [NSURL URLWithString:kIP];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
NSURLCredential *credential = [NSURLCredential
credentialWithUser:user
password:password
persistence:NSURLCredentialPersistenceForSession];
[operation setCredential:credential];
[[NSOperationQueue mainQueue] addOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (completionHandler) {
completionHandler(responseObject, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
[operation start];
}
Этот метод вызывается методом Login:
- (void)Login
{
NSString *rawString = [self.idTextField text];
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
[self.idTextField setText:[rawString stringByTrimmingCharactersInSet:whitespace]];
[userName UserLogin:self.idTextField.text andPassWordExists:self.passwordTextField.text completionHandler:^(id responseObject, NSError *error) {
if (responseObject) {
[self.idTextField removeFromSuperview];
[self.passwordTextField removeFromSuperview];
[self.loginButton removeFromSuperview];
self.idTextField = nil;
self.passwordTextField = nil;
//self.loginButton = nil;
[self CreateMenu];
[indicatorView stopAnimating];
[indicatorView removeFromSuperview];
indicatorView = nil;
[loadingView removeFromSuperview];
loadingView = nil;
}else{
[self CustomAlert:@"Sorry Login Failed, User and/or Passsword Incorrect"];
[indicatorView stopAnimating];
[indicatorView removeFromSuperview];
indicatorView = nil;
[loadingView removeFromSuperview];
loadingView = nil;
}
}];
}
И я пытаюсь очистить сеанс с LogoutButtonPressed:
- (void)LogoutButtonPressed
{
//@TODO: Fix Logout
NSDictionary *credentialsDict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials];
if ([credentialsDict count] > 0) {
NSEnumerator *protectionSpaceEnumerator = [credentialsDict keyEnumerator];
id urlProtectionSpace;
while (urlProtectionSpace = [protectionSpaceEnumerator nextObject]) {
NSEnumerator *userNameEnumerator = [[credentialsDict objectForKey:urlProtectionSpace] keyEnumerator];
id userNameCred;
while (userNameCred = [userNameEnumerator nextObject]) {
NSURLCredential *cred = [[credentialsDict objectForKey:urlProtectionSpace] objectForKey:userNameCred];
NSLog(@"cred to be removed: %@", cred);
[[NSURLCredentialStorage sharedCredentialStorage] removeCredential:cred forProtectionSpace:urlProtectionSpace];
}
}
}
}
Я получил этот код из этого примера: http://www.springenwerk.com/2008/11/i-am-currently-building-iphone.html
Теперь моя проблема заключается в том, что когда я запускаю кнопку выхода из системы и затем запускаю метод входа без каких-либо полномочий, я все равно могу войти в систему. Если я выйду из системы, подождите 2–3 минуты и войдите в систему без НИКАКИХ ПОЛОЖЕНИЙ, я не могу войти. Почему он так себя ведет, почти как кредиты все еще сохраняются. Пожалуйста помоги.
ОБНОВИТЬ
Я попытался очистить кэш, куки и кредиты внутри LogoutButtonPressed:
NSURLCache *sharedCache = [NSURLCache sharedURLCache];
[sharedCache removeAllCachedResponses];
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookies];
id cookie;
for (cookie in cookies) {
[cookieStorage deleteCookie:cookie];
}
NSDictionary *credentialsDict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials];
if ([credentialsDict count] > 0) {
NSEnumerator *protectionSpaceEnumerator = [credentialsDict keyEnumerator];
id urlProtectionSpace;
while (urlProtectionSpace = [protectionSpaceEnumerator nextObject]) {
NSEnumerator *userNameEnumerator = [[credentialsDict objectForKey:urlProtectionSpace] keyEnumerator];
id userNameCreds;
while (userNameCreds = [userNameEnumerator nextObject]) {
NSURLCredential *cred = [[credentialsDict objectForKey:urlProtectionSpace] objectForKey:userNameCreds];
[[NSURLCredentialStorage sharedCredentialStorage] removeCredential:cred forProtectionSpace:urlProtectionSpace];
}
}
}
и это все равно не сработало.
2 ответа
Эту проблему можно легко исправить, добавив случайное число в конец URL:
-(void)UserLogin:(NSString *)user andPassWordExists:(NSString *)password completionHandler:(void (^)(NSArray *resultsObject, NSError *error))completionHandler
{
NSInteger randomNumber = arc4random() % 999;
NSString *requestURL = [NSString stringWithFormat:@"%@?cache=%ld",kIP,(long)randomNumber];
NSURL *url = [NSURL URLWithString:requestURL];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
initWithRequest:request];
NSURLCredential *credential = [NSURLCredential
credentialWithUser:user
password:password
persistence:NSURLCredentialPersistenceForSession];
[operation setCredential:credential];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[[NSOperationQueue mainQueue] addOperation:operation];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if (completionHandler) {
completionHandler(responseObject, nil);
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if (completionHandler) {
completionHandler(nil, error);
}
}];
[operation start];
}
И убедитесь, что у вас есть случайное число в конце всех URL, которые вы звоните.
LogoutButtonPressed удаляет учетные данные из NSURLCredentialStorage, перебирая те же учетные данные - NSEnumerator этого не поддерживает. Видите ли вы сообщение "кредит будет удален" в журнале?
Вместо этого вы можете попробовать метод _resetCredentials из https://developer.apple.com/library/ios/samplecode/AdvancedURLConnections/Listings/CredentialsController_m.html.
Независимо от того, имеет ли это значение, было бы интересно изучить вывод _dumpCredentials как до, так и после вызова resetCredentials, или, что еще лучше, сделать дамп в методе входа в систему и посмотреть, есть ли изменения сразу после сброса. а потом через 2-3 минуты.
Является ли self.passwordTextField.text очищается? В случае отсутствия учетных данных, когда он входит в систему, делает NSURLCredential credentialWithUser:
дать тебе ноль?