2012-08-23 107 views
13

对客户端API的更新已将HTTPBasicAuthication方法替换为OAuth2 Bearer授权标头。OAuth 2承载者授权标头

随着旧的API我会做到以下几点:

NSURLCredential *credential = [NSURLCredential credentialWithUser:self.account.username 
                 password:self.account.token 
                 persistence:NSURLCredentialPersistenceForSession]; 

NSURLProtectionSpace *space = [[NSURLProtectionSpace alloc] initWithHost:kAPIHost 
                    port:443 
                   protocol:NSURLProtectionSpaceHTTPS 
                    realm:@"my-api" 
                authenticationMethod:NSURLAuthenticationMethodHTTPBasic]; 

但是,这不会与Bearer头工作。

NSString *authorization = [NSString stringWithFormat:@"Bearer %@",self.account.token]; 
[urlRequest setValue:authorization forHTTPHeaderField:@"Authorization"]; 

但有了这个解决方案的问题是,API重定向大多数的调用其他网址,这必须做:

现在通常我只会把它加像这样添加标题我自己与安全。 NSURLRequest获得重定向后,授权标头将从请求中删除,并且由于我无法将承载方法添加到NSURLCredentialStorage,因此它在重定向后无法再进行身份验证。

什么是一个很好的解决方案?我只能想到赶上重定向并修改NSURLRequest,所以它包括Bearer标题。但是如何?

回答

15

经过很多研究后,我发现当呼叫重定向时,我只需要替换NSURLRequest

不像我想要的那样好,但是确实有效。

我用AFNetworking并添加了重定向块,那么请检查是否如果不是我创建一个新的NSMutableURLRequestAuthorization头仍设置,并设置所有属性相匹配的旧请求(我知道我可以只创建一个可变副本):

[requestOperation setRedirectResponseBlock:^NSURLRequest *(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse) { 

    if ([request.allHTTPHeaderFields objectForKey:@"Authorization"] != nil) { 
     return request; 
    } 

    NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:request.URL cachePolicy:request.cachePolicy timeoutInterval:request.timeoutInterval]; 
    NSString *authValue = [NSString stringWithFormat:@"Bearer %@", self.account.token]; 
    [urlRequest setValue:authValue forHTTPHeaderField:@"Authorization"]; 

    return urlRequest; 

}]; 
+1

你是一个传奇人物。我遇到了同样的问题,并处理重定向修复它。 – rawbeans

4

我使用AFNetworking图书馆

查找AFHttpClient.m,你有一个方法

- (void)setAuthorizationHeaderWithToken:(NSString *)token { 
    [self setDefaultHeader:@"Authorization" value:[NSString stringWithFormat:@"Token token=\"%@\"", token]]; 
} 

具有以下或者如果你需要它的背面兼容性保持它的使用不同的名称添加和使用该名称

- (void)setAuthorizationHeaderWithToken:(NSString *)token { 
    [self setDefaultHeader:@"Authorization" value:[NSString stringWithFormat:@"Bearer %@", token]]; 
} 

然后进行与OAuth访问令牌请求替换此方法。 (下面是一个GET方法服务)

NSURL *url = [EFServiceUrlProvider getServiceUrlForMethod:methodName]; 
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; 
    [httpClient setAuthorizationHeaderWithToken:@"add your access token here"]; 

    [httpClient getPath:@"" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     NSString *response = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     // 
    }]; 

更新


使用OAuth2用户端AFNetworking写了亚光

https://github.com/AFNetworking/AFOAuth2Client

+0

不,当请求被重定向时,那么你将失去不记名令牌。 – rckoenes

1

如果你碰巧有Django的这个问题rest框架和路由器的问题可能与NSUrlRequest修剪的尾部斜线有关。如果斜线被剪裁的Django然后将重定向您的要求,以避免这一点,你可以使用Trailing_slash =真这样

router = routers.DefaultRouter(trailing_slash=False) 

这样,不是你的授权头也不是你的参数会迷路。

希望这节省了一些人的时间。

+1

没有Django,但ASP.net,我也看到它与PHP。只要URL重定向发生,授权就被清除。这是正常的行为,在收到403之后,再次使用Authorization标头完成调用。问题是,“承载者”头不被很好地支持。 – rckoenes

+0

哇。我们一直在使用Django休息,并试图弄清楚为什么IOS没有发送授权令牌标头,这就是它,NSURLRequest删除了尾部斜线 – yeahdixon