首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >目标c clear NSURLCredential - NSURLCredentialPersistenceForSession

目标c clear NSURLCredential - NSURLCredentialPersistenceForSession
EN

Stack Overflow用户
提问于 2015-04-09 19:21:03
回答 2查看 2.1K关注 0票数 11

我在这个方法中使用NSURLCredentials

代码语言:javascript
复制
-(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:

代码语言:javascript
复制
-(void)logout
{
   //Clear NSURLCredentialPersistenceForSession
}

我该怎么做呢?我是要重置NSURLCredentials,还是要清除它们?

更新

我找到了这个解决方案:

代码语言:javascript
复制
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];

        }

    }

出发地:Using NSURLCredentialPersistenceForSession while request and then clearing the credentials on logout still persist the cerdentials

这是最好的方法吗?我只存了一张证件。另外,这段代码在这一行上给了我一个警告:

代码语言:javascript
复制
NSURLCredential *credential = [spaceDictionary objectForKey:userName];

这是warning...how,我要删除这个警告吗?

代码语言:javascript
复制
/Users/jsuske/Documents/SSiPad(Device Only)ios7/SchedulingiPadApplication/ViewControllers/LHLoginController.m:496:73: Local declaration of 'userName' hides instance variable

更新

好的,我有三个方法:UserLogin,Login和LogoutButtonPressed

UserLogin:我使用AFNetworking连接到一个使用NSURLCredential进行身份验证的NSURLCredential,如下所示:

代码语言:javascript
复制
-(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方法正在调用此方法:

代码语言:javascript
复制
- (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来结束我的会议:

代码语言:javascript
复制
- (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中的缓存、cookie和tried:

代码语言:javascript
复制
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];
        }
    }
}

但还是没起作用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-15 14:42:36

通过在URL末尾添加一个随机数,可以很容易地解决此问题:

代码语言:javascript
复制
-(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的末尾都有一个随机数。

票数 5
EN

Stack Overflow用户

发布于 2015-04-12 01:22:10

LogoutButtonPressed正在从NSURLCredentialStorage中删除凭据,同时迭代相同的凭据-- NSEnumerator不支持这一点。您是否在日志中看到“将被移除的”消息?

您可以尝试使用来自_resetCredentials的m.html方法。

不管这是否有区别,检查resetCredentials调用之前和之后的_dumpCredentials输出都会很有趣,或者最好还是在登录方法中进行转储,并查看在重置之后以及2-3分钟后是否有更改。

self.passwordTextField.text被清除了吗?在它登录的无凭据情况下,NSURLCredential credentialWithUser:是否给出了零?

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29547134

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档