OAuth 2承载授权标头
通过更新客户端的API,HTTPBasicAuthication方法已替换为OAuth2 Bearer
Authorization标头。
使用旧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
它在重定向后无法再进行身份validation。
什么是好的解决方案? 我只能想到捕获重定向并修改NSURLRequest
因此它确实包含了Bearer
标头。 但是怎么样?
经过大量研究后,我发现在调用重定向时我只需要替换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; }];
我正在使用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 Client
如果您碰巧遇到Djangorest框架和路由器的这个问题,问题可能与NSUrlRequest剪切的尾部斜杠有关。 如果尾部斜杠被剪裁,那么django将不得不重定向你的请求,为了避免这种情况你可以使用Trailing_slash = True这样
router = routers.DefaultRouter(trailing_slash=False)
这样你的授权标题和参数都不会丢失。
希望这能节省一些时间。