Twitter仅应用程序身份验证始终返回401

时间:2015-11-18 05:03:23

标签: ios swift twitter oauth alamofire

我正在尝试使用App only auth进行身份验证,并且我成功获取了持有者令牌,但是当我尝试调用REST API时,我总是收到401错误,这是我的代码:

private var accessToken: String?
private let consumerKey = "*********"
private let consumerSecret = "*********"
private let baseUrlString = "https://api.twitter.com/1.1/"
private let pageSize = 20

private func authenticate(completionBlock: Void -> ()) {

    if accessToken != nil {
        completionBlock()
    }

    let credentials = "\(consumerKey):\(consumerSecret)"
    let headers = ["Authorization": "Basic \(credentials.getBase64())"]
    let params: [String : AnyObject] = ["grant_type": "client_credentials"]

    Alamofire.request(.POST, "https://api.twitter.com/oauth2/token", headers: headers, parameters: params)
        .responseJSON { response in
            if let JSON = response.result.value {
                self.accessToken = JSON.objectForKey("access_token") as? String
                completionBlock()
            }
    }
}

func getTimelineForScreenName(screenName: String) {

    authenticate {

        guard let token = self.accessToken else {
            // TODO: Show authentication error
            return
        }

        let headers = ["Authorization": "Bearer \(token.getBase64())"]
        let params: [String : AnyObject] = [
            "screen_name" : screenName,
            "count": self.pageSize
        ]
        Alamofire.request(.GET, self.baseUrlString + "statuses/user_timeline.json", headers: headers, parameters: params)
            .responseJSON { response in
                print(response.response)

                if let JSON = response.result.value {
                    print(JSON)
                }
        }
    }
}

...

private extension String {
    func getBase64() -> String {
        let credentialData = self.dataUsingEncoding(NSUTF8StringEncoding)!
        return credentialData.base64EncodedStringWithOptions([])
    }
}

我尝试过生成新密钥但没有尝试,也尝试了在iOS 9中发现的这个错误中建议的不要让Authorization标头在重定向上传递但是此请求没有使用任何重定向。< / p>

任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:7)

经过几个小时的调查后,我发现侥幸发现带有承载令牌的标题不应该编码为base64,所以标题看起来应该是这样的:
let headers = ["Authorization": "Bearer \(token)"]

我希望这可以帮助任何人尝试类似的东西,因为documentation说你必须使用base64编码的令牌。

  

步骤3:使用承载令牌验证API请求   承载令牌可用于向支持仅应用程序身份验证的API端点发出请求。要使用承载令牌,请构造一个普通的HTTPS请求,并包含一个值为Bearer <base64 bearer token value from step 2>的Authorization标头。不需要签名。