通过更新客户端的API,HTTPBasicAuthication方法已替换为OAuth2 Bearer
授权标头。
使用旧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将大多数调用重定向到其他URL,这与安全性有关。
重定向NSURLRequest
后,将从请求中删除Authorization标头,因为我无法将Bearer方法添加到NSURLCredentialStorage
,因此在重定向后无法再对其进行身份验证。
什么是好的解决方案?我只能考虑捕获重定向并修改NSURLRequest
,因此它包含Bearer
标头。但是如何?
答案 0 :(得分:15)
经过大量研究后,我发现在调用重定向时我只需要替换NSURLRequest
。
不像我希望的那样好,但确实有效。
我使用AFNetworking
并添加了重定向块,然后检查Authorization
标头是否仍然设置,如果不是我创建新的NSMutableURLRequest
并设置所有属性以匹配旧请求(我知道我本可以创建一个可变副本):
[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 :(得分:4)
我正在使用AFNetworking Library
找到 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) {
//
}];
在matt
编写的AFNetworking上使用Oauth2客户端答案 2 :(得分:1)
如果你碰巧遇到Django休息框架和路由器这个问题,问题可能与NSUrlRequest剪切的尾部斜线有关。如果尾部斜线被剪裁,那么django将不得不重定向您的请求,为避免这种情况,您可以像这样使用Trailing_slash = True
router = routers.DefaultRouter(trailing_slash=False)
这样,你的授权标题和参数都不会丢失。
希望这能节省一些时间。