由於服務器端對於調用API獲取數據接口進行了限制,需要在調用API之前獲取一個access-token,所以需要在iOS裏實現獲取這個access-token的功能。 服務器端是在ASP.NET中基於Owin OAuth使用Client Credentials Grand方式發放Token,具體的實現細節可以參考這篇博客。
根據服務端提供的測試代碼,如下:
private async Task GetAccessToken(string grantType, string userName = null, string password = null) { var parameters = new Dictionary<string, string>(); parameters.Add("client_id", "1234"); parameters.Add("client_secret", "5678"); var clientId = "1234"; var clientSecret = "5678"; var parameters = new Dictionary<string, string>(); parameters.Add("grant_type", grantType); if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password)) { parameters.Add("username", userName); parameters.Add("password", password); } _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue( "Basic", Convert.ToBase64String(Encoding.ASCII.GetBytes(clientId + ":" + clientSecret)) ); var response = await _httpClient.PostAsync("/token", new FormUrlEncodedContent(parameters)); var responseValue = await response.Content.ReadAsStringAsync(); }
通過上面的代碼就可以看出在客戶端需要做下面幾件事情:
1、對client_id和client_secret進行Base64String編碼,在iOS裏有專門對NSString進行Base64編碼的庫,具體請參見NSData+Base64。
2、將grant_type爲"client_credentials"作爲參數Post給服務器地址;
3、最後需要注意的是AFNetWorking 實現Basic 驗證的時候,傳值的時候注意Basic後面有一個空格,然後設置Content-Type爲"application/x-www-form-urlencoded;charset=UTF-8"。這樣就可以拿到access_token。代碼如下:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; NSString *client_id = @"1234"; NSString *client_secret = @"5678"; NSString *authStr = [NSString stringWithFormat:@"%@:%@",client_id,client_secret]; NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding]; NSString *authValue = [NSString stringWithFormat:@"Basic %@",[authData base64EncodedStringWithOptions:0]]; [manager.requestSerializer setValue:authValue forHTTPHeaderField:@"Authorization"]; [manager.requestSerializer setValue:@"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"]; NSDictionary *params = @{@"grant_type":@"client_credentials"}; [manager POST:@"http://api.cnblogs.com/token" parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"JSON: %@", responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Error: %@", [error description]); }];
這樣就完成了本次場景的需求。實驗以Basic 驗證方式獲取access_token。這樣拿到服務端的授權以後就可以調用公開的API列表啦。