iOS - Swift - Bing 图片搜索 API 使用 Alamofire 进行身份验证

iOS - Swift - Bing Image Search API Authentication with Alamofire

正在尝试使用 Bing API 检索 Swift 中的图像,但没有成功。从我在 Whosebug 上收集的其他类似问题以及 Bing API 文档 (https://onedrive.live.com/view.aspx?resid=9C9479871FBFA822!112&app=Word&authkey=!ANNnJQREB0kDC04) 中,您必须将请求发送到 api将授权 header 设置为 Bing API 帐户密钥的 base64 编码版本。所以我尝试了以下方法:

let url = NSURL(string: Settings.bingImageApi + "&Query=" + keyword)!
let plainText = bingAPIKey.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let base64 = plainText!.base64EncodedStringWithOptions(nil)

let manager = Alamofire.Manager.sharedInstance
manager.session.configuration.HTTPAdditionalHeaders = [
  "Authorization": "Basic \(base64)"
]

manager
  .request(.POST, url, parameters: nil, encoding: .JSON)
  .responseJSON { (request, response, data, error) -> Void in
    println(response)
}

并且 println(error) 语句产生以下内容:

{ status code: 401, headers {
    "Access-Control-Allow-Credentials" = false;
    "Access-Control-Allow-Headers" = "Content-Type, Authorization, DataServiceVersion, MaxDataServiceVersion";
    "Access-Control-Allow-Methods" = "GET, POST, PUT, DELETE, OPTIONS";
    "Access-Control-Allow-Origin" = "*";
    "Access-Control-Expose-Headers" = "DataServiceVersion, MaxDataServiceVersion";
    "Access-Control-Max-Age" = 604800;
    "Content-Length" = 91;
    Date = "Thu, 16 Jul 2015 00:38:34 GMT";
    Server = "Microsoft-IIS/8.0";
    "Www-Authenticate" = "Basic Realm=\"\"";
    "X-Content-Type-Options" = nosniff;
    "X-Powered-By" = "ASP.NET";
}

授权通常需要用户名和密码,但在这种情况下只需要密码,而用户名可以为空。我将如何去指定密码值?我认为问题出在那个或 base64 编码有问题。

知道了。需要对整个 username:password 字符串进行编码,而不仅仅是一个值或另一个。在我修复了 400 错误(错误请求)之后,我通过在查询字符串周围添加单引号解决了这个问题。最终代码如下所示:

let keyword = "'\(currentSearchTerm)'".stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
let url = NSURL(string: Settings.bingImageApi + "&Query=" + keyword)!

let credentials = ":\(Settings.bingApiKey)"
let plainText = credentials.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let base64 = plainText!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))

let manager = Alamofire.Manager.sharedInstance
manager.session.configuration.HTTPAdditionalHeaders = [
  "Authorization": "Basic \(base64)"
]

manager
  .request(.POST, url, parameters: nil, encoding: .JSON)
  .responseJSON { (request, response, data, error) -> Void in
    println(data)
}