我正在尝试使用原生iOS NSURLSession
网址加载类创建一个使用OAuth2身份验证的iOS应用。我使用这里的指示获得了一个访问令牌:
我随后启动了该应用程序并运行了一个搜索查询
https://www.freesound.org/apiv2/search/text/?query=snare
请求标头字段如下所示(注意我的访问令牌未过期,我已经确认它与我在执行上述步骤时收到的相同)
{
"Authorization: Bearer" = MY_ACCESS_TOKEN;
}
这失败了:
{"detail": "Authentication credentials were not provided."}
响应标头如下所示:
{
Allow = "GET, HEAD, OPTIONS";
Connection = "keep-alive";
"Content-Type" = "application/json";
Date = "Sat, 31 Jan 2015 13:56:32 GMT";
Server = "nginx/1.2.1";
"Transfer-Encoding" = Identity;
Vary = "Accept, Cookie";
"Www-Authenticate" = "Bearer realm=\"api\"";
}
有趣的是,这并不总是发生。如果我多次重复整个过程,在两者之间删除应用程序,它最终会起作用。一旦它工作,它将继续工作,而我正在发展。有时然后当我回到它,说第二天,它停止工作,我需要重复这个删除和重新安装例程,让它恢复工作!
NSURLSession上有一个身份验证质询委托方法,如果实现则会调用该方法。这是一个“服务器信任”的挑战。这可能与它有关吗?您是否会期待这种性质的身份验证挑战?在上面提到的文档中没有提到它。
非常感谢任何帮助。
修改
这就是搜索文本(“小军”)GET调用的方式。
我基本上传递NSMutableURLRequest
,其网址设置为上述(https://www.freesound.org/apiv2/search/text/?query=snare
)。 useAccessToken
设置为YES
。
- (void)makeRequest:(NSMutableURLRequest *)request useAccessToken:(BOOL)useAccessToken completion:(CompletionBlock)completion {
NSAssert(completion, @"No completion block.");
if (useAccessToken) {
NSString *accessToken = [[ODMFreesoundTokenCache sharedCache] accessToken];
NSAssert(accessToken.length, @"No access token.");
[request addValue:accessToken forHTTPHeaderField:@"Authorization: Bearer"];
}
NSLog(@"Making request: %@ \n\nWith access token: %@", request, [[ODMFreesoundTokenCache sharedCache] accessToken]);
NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSInteger code = [(NSHTTPURLResponse *)response statusCode];
if (code == 200) {
if (!error) {
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(@"json: %@", json);
completion(json, error);
}
else {
completion(nil, error);
}
}
else {
NSString *reason = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSError *error = [NSError errorWithDomain:@"Request Error" code:code userInfo: reason ? @{NSLocalizedDescriptionKey : reason} : nil];
NSLog(@"error: %@", error);
completion(nil, error);
}
}];
[task resume];
}
答案 0 :(得分:1)
doc中描述的2个用于身份验证的流程对于设备而言并不“安全”。使用API密钥需要将秘密存储在设备中。
他们支持的OAuth2流程(authorization_code)需要服务器到服务器调用来交换实际令牌的代码(此步骤:http://www.freesound.org/docs/api/authentication.html#step-3)。此调用需要另一个凭证(client_secret
,您可能不应该存储在设备中。
您需要一台服务器来为您协商。或者是将code flow
翻译为token
的服务器。 (如图所示:https://auth0.com/docs/protocols#5)。