关于使用 Twitter 身份验证的错误身份验证数据 headers
Bad authentication data on using twitter authentication headers
我已经编写了一个 Python 程序来使用 OAuth
。我在使用访问令牌(以 Twitter 为例)访问服务资源时观察到一个问题。
我能够成功检索到 access_token
,但是如果我尝试在 Twitter 中将 access_token
用作 Authorization
header,则它不起作用。但是,如果我将其作为正常 url 参数传递,那么我会得到所需的结果。
parameters_access_resource = [
('oauth_consumer_key', self.consumerKey),
('oauth_signature_method', 'HMAC-SHA1'),
('oauth_timestamp', self._timestamp),
('oauth_nonce', self._nonce),
('oauth_version', '1.0'),
('oauth_token', self._accessToken),
('oauth_signature', self._signature)
]
以下方法有效:
urlLink = "https://api.twitter.com/1.1/account/settings.json"
url = "?".join((urlLink, urllib.urlencode(parameters_access_resource)))
reqobj = urllib2.Request(url,data=[])
resp = urllib2.urlopen(reqobj)
print resp.read()
问题:
根据 Twitter 文档,access_token
应作为 Authorization
header 传递,因此我将代码修改如下
headers = {
"Accept": "*/*",
"Connection": "close",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Content-Type" : "application/x-www-form-urlencoded",
"Host" : "api.twitter.com",
"Authorization" : self._getAuthorizationHeader(parameters_access_resource)
}
def _getAuthorizationHeader(self,params):
params = dict(params)
sortedParams = {}
sortedParams = collections.OrderedDict(sorted(params.items()))
authHeader = (
'%s="%s"' % (k, v) for k, v in sortedParams.iteritems())
retval = "OAuth " + ', '.join(authHeader)
return retval
url = "https://api.twitter.com/1.1/account/settings.json"
reqobj = urllib2.Request(url,data=[],headers=headers)
resp = urllib2.urlopen(reqobj)
print resp.read()
报告以下错误,我尝试了不同的组合,包括使用 requests
模块,但我无法找出问题所在。
{"errors":[{"code":215,"message":"Bad Authentication data."}]}
有人可以指导我如何解决这个问题。
P.S : 我知道已经有很多模块可用于此任务,但我编写此代码是为了学习目的。
已找到解决方案,构建 header 时出现问题,我不是 percent-encoding
Authentication
header 的值。下面的代码解决了问题
def _getAuthorizationHeader(self,params):
params = dict(params)
sortedParams = {}
sortedParams = collections.OrderedDict(sorted(params.items()))
authHeader = (
'%s="%s"' % (k, self._url_encode(v)) for k, v in sortedParams.iteritems())
retval = "OAuth " + ', '.join(authHeader)
return retval
def _url_encode(self,s):
return urllib.quote(str(s),safe='')
我已经编写了一个 Python 程序来使用 OAuth
。我在使用访问令牌(以 Twitter 为例)访问服务资源时观察到一个问题。
我能够成功检索到 access_token
,但是如果我尝试在 Twitter 中将 access_token
用作 Authorization
header,则它不起作用。但是,如果我将其作为正常 url 参数传递,那么我会得到所需的结果。
parameters_access_resource = [
('oauth_consumer_key', self.consumerKey),
('oauth_signature_method', 'HMAC-SHA1'),
('oauth_timestamp', self._timestamp),
('oauth_nonce', self._nonce),
('oauth_version', '1.0'),
('oauth_token', self._accessToken),
('oauth_signature', self._signature)
]
以下方法有效:
urlLink = "https://api.twitter.com/1.1/account/settings.json"
url = "?".join((urlLink, urllib.urlencode(parameters_access_resource)))
reqobj = urllib2.Request(url,data=[])
resp = urllib2.urlopen(reqobj)
print resp.read()
问题:
根据 Twitter 文档,access_token
应作为 Authorization
header 传递,因此我将代码修改如下
headers = {
"Accept": "*/*",
"Connection": "close",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
"Content-Type" : "application/x-www-form-urlencoded",
"Host" : "api.twitter.com",
"Authorization" : self._getAuthorizationHeader(parameters_access_resource)
}
def _getAuthorizationHeader(self,params):
params = dict(params)
sortedParams = {}
sortedParams = collections.OrderedDict(sorted(params.items()))
authHeader = (
'%s="%s"' % (k, v) for k, v in sortedParams.iteritems())
retval = "OAuth " + ', '.join(authHeader)
return retval
url = "https://api.twitter.com/1.1/account/settings.json"
reqobj = urllib2.Request(url,data=[],headers=headers)
resp = urllib2.urlopen(reqobj)
print resp.read()
报告以下错误,我尝试了不同的组合,包括使用 requests
模块,但我无法找出问题所在。
{"errors":[{"code":215,"message":"Bad Authentication data."}]}
有人可以指导我如何解决这个问题。
P.S : 我知道已经有很多模块可用于此任务,但我编写此代码是为了学习目的。
已找到解决方案,构建 header 时出现问题,我不是 percent-encoding
Authentication
header 的值。下面的代码解决了问题
def _getAuthorizationHeader(self,params):
params = dict(params)
sortedParams = {}
sortedParams = collections.OrderedDict(sorted(params.items()))
authHeader = (
'%s="%s"' % (k, self._url_encode(v)) for k, v in sortedParams.iteritems())
retval = "OAuth " + ', '.join(authHeader)
return retval
def _url_encode(self,s):
return urllib.quote(str(s),safe='')