Django oauth2令牌请求在Swift Alamofire上失败
我正在构建一个iOS客户端和一个django后端服务。系统之间的连接是OAUTH2,由django-OAUTH2-toolkit实现 尽管在curl中执行的以下命令有效(返回访问令牌): 然后,我在django-oauth2-toolkit源代码中跟踪了Django oauth2令牌请求在Swift Alamofire上失败,django,swift,curl,oauth-2.0,alamofire,Django,Swift,Curl,Oauth 2.0,Alamofire,我正在构建一个iOS客户端和一个django后端服务。系统之间的连接是OAUTH2,由django-OAUTH2-toolkit实现 尽管在curl中执行的以下命令有效(返回访问令牌): 然后,我在django-oauth2-toolkit源代码中跟踪了InvalidClientError,发现在以下文件的突出显示的片段中引发了异常: oauthlib/oauth2/rfc6749/grant\u types/resource\u owner\u password\u credentials.p
InvalidClientError
,发现在以下文件的突出显示的片段中引发了异常:
oauthlib/oauth2/rfc6749/grant\u types/resource\u owner\u password\u credentials.py
if self.request_validator.client_authentication_required(request):
log.debug('Authenticating client, %r.', request)
print(request) # I included this print message to inspect the request variable in console.
if not self.request_validator.authenticate_client(request):
log.debug('Client authentication failed, %r.', request)
raise errors.InvalidClientError(request=request) # RAISED!
我加入了print(request)
行来检查curl和Alamofire提出的请求之间的差异。主要区别在于curl版本包含一个授权密钥:
'Authorization': 'Basic Z3ZFSjVXejloUGgybUJmdDNRaGhXZnlhNHpETG5KY3V6djJldWMwcjpSbVNPMkpwRFQ4bHp1UVFDYXN3T3dvVFkzRTBia01YWWxHVHNMcG5JUGZCUHFjbHJSZE5EOXQzd3RCS2xwR09MNWs1bEE4S2hmRUkydEhvWmx3ZVRKZkFXUDM4OERZa1NTZ0RvS0p3WjUyejRSQ29WRkZBS01RS1lydEpsTWNXag=='
阿拉莫菲尔的请求没有
我高度怀疑这是罪魁祸首,但我真的不知道从现在起还能做什么。我真的很感激任何智慧。找到了答案
当我正在阅读关于HTTP协议的RFC文档时,这一部分引起了我的注意
具体来说,
要接收授权,客户端将发送用户ID和密码,
由一个冒号(“:”)字符分隔,在base64[5]中
凭据中的编码字符串
Alamofire似乎没有像预期的那样,以64位编码clientId和clientSecret。显然,curl会自动执行此操作。因此,我做了以下工作:
第一个编码:
static let clientData: NSData = "\(clientId):\(clientSecret)".dataUsingEncoding(NSUTF8StringEncoding)!
static let client64String = clientData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.init(rawValue: 0))
然后使用结果值设置请求标头:
let request = "http://localhost:8000/o/token/"
var URLRequest = NSMutableURLRequest(URL: NSURL(string: request)!)
URLRequest.HTTPMethod = "POST"
let parameters = ["grant_type": "password",
"username": in_username.text!,
"password": in_password.text!,
]
let encoding = Alamofire.ParameterEncoding.URL
(URLRequest, _) = encoding.encode(URLRequest, parameters: parameters)
// SOLUTION!
URLRequest.setValue("Basic \(Authentication.client64String)", forHTTPHeaderField: "Authorization")
Alamofire.request(URLRequest)
.responseJSON { response in
let data = response
print(data)
}
然后,我收到了预期的令牌作为响应
let request = "http://\(Authentication.clientId):\(Authentication.clientSecret)@localhost:8000/o/token/"
var URLRequest = NSMutableURLRequest(URL: NSURL(string: request)!)
URLRequest.HTTPMethod = "POST"
let parameters = ["grant_type": "password", "username": in_username.text!, "password": in_password.text!]
let encoding = Alamofire.ParameterEncoding.URL
(URLRequest, _) = encoding.encode(URLRequest, parameters: parameters)
URLRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
Alamofire.request(URLRequest)
.responseJSON { response in
let data = response
print(data)
}
let request = "http://localhost:8000/o/token/"
var URLRequest = NSMutableURLRequest(URL: NSURL(string: request)!)
URLRequest.HTTPMethod = "POST"
let parameters = ["grant_type": "password",
"username": in_username.text!,
"password": in_password.text!,
]
let encoding = Alamofire.ParameterEncoding.URL
(URLRequest, _) = encoding.encode(URLRequest, parameters: parameters)
// SOLUTION!
URLRequest.setValue("Basic \(Authentication.client64String)", forHTTPHeaderField: "Authorization")
Alamofire.request(URLRequest)
.responseJSON { response in
let data = response
print(data)
}