I want to sent my assignment gist in the JSON Response :
{
gist :"",
email :""
}
to an API using TOTP(Time-based one-time password) method . Is there any solution available for that?
Although you have to do it by yourself but still if you invested lot's of time and didn't find solution then you can use my solution for that :
import requests
import hmac
import hashlib
import time
import sys
import struct
import json
from requests.auth import HTTPBasicAuth
root = "YOUR API RESIDES HERE"
content_type = "application/json"
userid = "YOUR USERID"
secret_suffix = "YOUR SECRET SUFFIX OR KEY"
shared_secret = userid+secret_suffix
timestep = 30
T0 = 0
def HOTP(K, C, digits=10):
"""HTOP:
K is the shared key
C is the counter value
digits control the response length
"""
K_bytes = str.encode(K)
C_bytes = struct.pack(">Q", C)
hmac_sha512 = hmac.new(key = K_bytes, msg=C_bytes, digestmod=hashlib.sha512).hexdigest()
return Truncate(hmac_sha512)[-digits:]
def Truncate(hmac_sha512):
"""truncate sha512 value"""
offset = int(hmac_sha512[-1], 16)
binary = int(hmac_sha512[(offset *2):((offset*2)+8)], 16) & 0x7FFFFFFF
return str(binary)
def TOTP(K, digits=10, timeref = 0, timestep = 30):
"""TOTP, time-based variant of HOTP
digits control the response length
the C in HOTP is replaced by ( (currentTime - timeref) / timestep )
"""
C = int ( time.time() - timeref ) // timestep
return HOTP(K, C, digits = digits)
data = {
"github_url": "YOUR GITHUB URL",
"contact_email": "YOUR EMAIL",
"solution_language": "IT IS OPTIONAL"
}
passwd = TOTP(shared_secret, 10, T0, timestep).zfill(10)
resp = requests.post(root, auth=HTTPBasicAuth(userid, passwd), data=json.dumps(data))
print(resp.json())
I hope this works !!
Happy Coding !!
Related
How do I implement the below python/Java/PHP code in NodeJs?
ReferenceLink
Python Code (for reference):
import hashlib
import hmac
import base64
#app.route('/notify_url/', methods=["POST"])
def notify_url_process():
postData = {
"orderId" : request.form['orderId'],
"orderAmount" : request.form['orderAmount'],
"referenceId" : request.form['referenceId'],
"txStatus" : request.form['txStatus'],
"paymentMode" : request.form['paymentMode'],
"txMsg" : request.form['txMsg'],
"txTime" : request.form['txTime'],
}
signatureData = postData["orderId"] + postData["orderAmount"] + postData["referenceId"] + postData["txStatus"] + postData["paymentMode"] + postData["txMsg"] + postData["txTime"]
message = bytes(signatureData).encode('utf-8')
#get secret key from your config
secret = bytes(secretKey).encode('utf-8')
signature = base64.b64encode(hmac.new(secret,
message,digestmod=hashlib.sha256).digest())
So far, I was able to come up with the below code. However, the generated and received signatures do not match.
var hmac = crypto.createHmac('sha256', "appSecret"); //Key hidden for posting here
hmac.update(request.body.orderId + request.body.orderAmount+request.body.referenceId+request.body.txStatus+request.body.paymentMode+request.body.txMsg+request.body.txTime);
let generatedSignature = hmac.digest('hex');
let isSignatureValid = generatedSignature == request.body.cashfreeSignature;
console.log(isSignatureValid);
Have you tried comparing the base64 encoding as opposed to the hex value?
Instead of
let generatedSignature = hmac.digest('hex');
use
let generatedSignature = hmac.digest('base64');
I am trying to send an authentificated message over an API at iconomi.com.
I am used to sign message when dealing with other exchange API, but can't be authentificated with this specific one.
I read the official documentation for authentification:
You generate the ICN-SIGN header by creating a sha512 HMAC using the
base64-decoded secret key on the prehash string timestamp + method +
requestPath + body (where + represents string concatenation) and
base64-encode the output, where:
the timestamp value is the same as the ICN-TIMESTAMP header. the body
is the request body string or omitted if there is no request body
(typically for GET requests). method must always be in upper case
Example: base64_encode(HMAC_SHA512(secret_key, timestamp + upper_case(method) + requestPath + body))
I found also a java client example on the official github, please see bellow signature generation in java :
private String generateServerDigest(String method, String uri, long timestamp, String body) {
//return timestamp + request.getMethodValue() + uri + body;
String checkDigestString = timestamp + method + uri + body;// "GET+/v1/daa-list+123123123"; //timestamp in epoch milliseconds
// hash server composited digest with algorithm and apikeys secret
SecretKeySpec signingKey = new SecretKeySpec(apiSecret.getBytes(), "HmacSHA512");
Mac mac;
try {
mac = Mac.getInstance(signingKey.getAlgorithm());
mac.init(signingKey);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
log.warn("Could not ={}", signingKey.getAlgorithm());
return null;
}
return Base64.getEncoder().encodeToString(mac.doFinal(checkDigestString.getBytes()));
}
Please note that checkDigestString code timestamp + method + uri + body and comment GET+/v1/daa-list+123123123 are already different on the official doc.
And this is my python implementation attempt :
def sign(timestamp,method,requestPath,body):
global api_secret
base64_decoded_secret_key = base64.b64decode(api_secret)
content_to_hash = (str(timestamp) + method.upper() + requestPath + body).encode('utf-8')
sign_digest = hmac.new(base64_decoded_secret_key, content_to_hash , hashlib.sha512).digest()
return base64.b64encode(sign_digest).decode('utf-8')
When I try this signature method with requestPath = "/v1/user/balance" (which required to be authentificated), it fail without error...
Does any one used with both java and python may help me to convert this signature method to python ?
This code will work for GET:
import time,requests
import hashlib,hmac,base64
api_key = "my api key"
api_secret = "my api secret"
defaut_encoding = "utf8"
uri = "https://api.iconomi.com"
requestPath = "/v1/user/balance"
api_url_target = uri+requestPath # https://api.iconomi.com/v1/user/balance
method="GET"
body=""
icn_timestamp = int(1000.*time.time())
message = (str(icn_timestamp) + method.upper() + requestPath + body).encode(defaut_encoding)
signature_digest = hmac.new(api_secret.encode(defaut_encoding), message, hashlib.sha512).digest() #here digest is byte
b64_signature_digest= base64.b64encode(signature_digest).decode(defaut_encoding)
headers_sign= {
"ICN-API-KEY":api_key,
"ICN-SIGN":b64_signature_digest,
"ICN-TIMESTAMP":str(icn_timestamp)
}
s=requests.session()
res = s.get(api_url_target,headers=headers_sign,timeout=3, verify=True).content
print (res)
Update for #Karl comment, this code will work for POST:
import time,requests
import hashlib,hmac,base64,json
api_key = "my api key"
api_secret = "my api secret"
ticker = "my ticker strategy"
defaut_encoding = "utf8"
uri = "https://api.iconomi.com"
requestPath = "/v1/strategies/"+ticker+"/structure"
api_url_target = uri+requestPath # https://api.iconomi.com/v1/strategies/{my ticker strategy}/structure
method="POST"
body="{'ticker': ticker, 'values': [{'rebalancedWeight': 1., 'targetWeight':1., 'assetTicker': 'XMR', 'assetName': 'Monero', 'assetCategory': 'Privacy'}]}"
icn_timestamp = int(1000.*time.time())
message = (str(icn_timestamp) + method.upper() + requestPath + body).encode(defaut_encoding)
signature_digest = hmac.new(api_secret.encode(defaut_encoding), message, hashlib.sha512).digest() #here digest is byte
b64_signature_digest= base64.b64encode(signature_digest).decode(defaut_encoding)
headers_sign= {
"ICN-API-KEY":api_key,
"ICN-SIGN":b64_signature_digest,
"ICN-TIMESTAMP":str(icn_timestamp)
}
s=requests.session()
res = s.post(api_url_target,headers=headers_sign,json = json.loads(body), timeout=3, verify=True).content
print (res)
I am trying to use a WooCommerce Python client to make a POST request but
I get "Provided Signature does not match"
The client I use is from:
WooCommerce API OAuth in python
This is my client:
#!/usr/bin/env python
import requests
import random
import string
import time
from hashlib import sha1
import hmac
import binascii
import re
import collections
from urllib import quote, urlencode
def uksort(dictionary):
return collections.OrderedDict(sorted(dictionary.items(), cmp = cmp))
class WooCommerce(object):
def __init__(self, consumer_key, consumer_secret, endpoint):
self.consumer_key = consumer_key
self.consumer_secret = consumer_secret
self.endpoint = endpoint
def _make_request(self, resource, params, method = "GET"):
oauth_params = {
"oauth_consumer_key": self.consumer_key,
"oauth_nonce": self._gen_nonce(),
"oauth_timestamp": self._gen_timestamp(),
"oauth_signature_method": "HMAC-SHA1",
}
oauth_params["oauth_signature"] = self._gen_signature(resource, dict(params.items() + oauth_params.items()), method)
params = dict(params.items() + oauth_params.items())
if method == "GET":
print self.endpoint + resource + "?" + urlencode(params)
elif method == "POST":
print self.endpoint + resource + "?" + urlencode(params)
req = urllib.request.Request(self.endpoint + resource + "?" + urlencode(params))
open = urllib.request.urlopen(req)
requestContent = open.read()
#print(open)
def _gen_nonce(self):
ran_string = ''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(32)).encode("base64")
alnum_hash = re.sub(r'[^a-zA-Z0-9]', "", ran_string)
return alnum_hash
def _gen_timestamp(self):
return int(time.time())
def _gen_signature(self, resource, params, method):
base_request_uri = quote(self.endpoint + resource, safe = "")
normalized_params = self._normalize_params(params)
sorted_params = uksort(normalized_params)
query_string = "%26".join([key + "%3D" + value for key, value in sorted_params.iteritems()])
raw_string = method + "&" + base_request_uri + "&" + query_string
hashed = hmac.new(self.consumer_secret, raw_string, sha1)
return binascii.b2a_base64(hashed.digest()).rstrip("\n")
def _normalize_params(self, params):
normalized = {}
for key, value in params.iteritems():
key = quote(str(key), safe = "")
value = quote(str(value), safe = "")
normalized[key] = value
return normalized
And I use it like this from another class:
woo_client = WooCommerce('ck_7bb1951bee7454b2e29bf5eef9205e0e', 'cs_155cd9420201c0a7e140bebd6a9794c7', 'http://dima.bg/wc-api/v2')
data = {
"product": {
"title": "testname",
}
}
result = self.woo_client._make_request("/products/", data, 'POST')
Can you see something wrong with my URL ? Thanks for your time.
http://xxxxxxxxx.xx/wc-api/v2/products/?product=%7B%27title%27%3A+%27testname%27%7D&oauth_nonce=NThWODczRFIyWkxRNFZOVkUxNFdRSVo0QjFSNllIVFk&oauth_timestamp=1423647865&oauth_consumer_key=ck_7bb1951bee7454b2e29bf5eef9205e0e&oauth_signature_method=HMAC-SHA1&oauth_signature=3PSnEEf08gFthIRAr8AUKQiDjco%3D
I used your code as a starting point for my own solution to this problem and had some success! Here's what I did:
import requests
import random
import string
import time
from hashlib import sha1
import hmac
import binascii
import re
from urllib import quote, urlencode
import httplib2
from collections import OrderedDict
def key_compare(a, b):
return cmp(a[0], b[0])
class Restful_Client(object):
"""docstring for Restful_Client"""
def __init__(self, endpoint, consumer_key, consumer_secret):
super(Restful_Client, self).__init__()
self.consumer_key = consumer_key
self.consumer_secret = consumer_secret
self.endpoint = endpoint
def make_request(self, resource, params, method='GET' ):
oauth_params = {
'oauth_consumer_key': self.consumer_key,
'oauth_nonce': self.gen_nonce(),
'oauth_timestamp': self.gen_timestamp(),
'oauth_signature_method': 'HMAC-SHA1',
# 'oauth_version':'1.0'
}
oauth_params['oauth_signature'] = self.gen_signature(
resource,
OrderedDict( params.items() + oauth_params.items() ),
method
)
params = OrderedDict( params.items() + oauth_params.items() )
clean_params = self.sort_params(self.normalize_params(params))
uri = endpoint + resource
p_string = urlencode(clean_params)
print 'p string:'
print '\n'.join(p_string.split('&'))
return httplib2.Http().request(uri + '?' + p_string)
def gen_signature(self, resource, params, method):
base_request_uri = quote(self.endpoint + resource, safe = "")
clean_params = self.sort_params(
self.normalize_params(
self.normalize_params(
params
)
)
)
query_string = '%26'.join([
key + '%3D' + value\
for key, value in clean_params.iteritems()
])
raw_string = '&'.join([method, base_request_uri, query_string])
print "raw string: "
print '\n'.join(raw_string.split('%26'))
hashed = hmac.new(self.consumer_secret, raw_string, sha1)
return binascii.b2a_base64( hashed.digest() )[:-1]
def normalize_string(self, string):
return quote(str(string), safe="")
def normalize_params(self, params):
return OrderedDict( [
(self.normalize_string(key), self.normalize_string(value))\
for key, value \
in params.iteritems()
])
def sort_params(self, params):
return OrderedDict(sorted(
params.iteritems(),
cmp=key_compare
))
def gen_timestamp(self):
return int(time.time())
# return 1429451603
def gen_nonce(self):
return hex(self.gen_timestamp())
#todo: make this more secure
if __name__ == "__main__":
store_url = '<STORE URL HERE>'
api_base = 'wc-api'
api_ver = 'v2'
endpoint = "%s/%s/%s/" % (store_url, api_base, api_ver)
consumer_key = '<CK HERE>'
consumer_secret = '<CS HERE>'
resource = 'customers'
parameters = {
# 'fields':'id,first_name'
}
rc = Restful_Client(endpoint, consumer_key, consumer_secret)
r, c = rc.make_request(resource, parameters, 'GET')
print r
print c
What I would suggest is ensuring that the parameters are encoded the correct number of times, I found that the parameters needed to be "double encoded" to work. It looks like in this case your parameters (the key and value strings) are not "double encoded" as suggested in the API doc http://woothemes.github.io/woocommerce-rest-api-docs/#authentication
You can test this hypothesis by trying a simple GET request without any parameters like the one in my code. if that works then that might be your problem. Good luck!
I'm trying to write python authentication bot for: https://comkort.com/page/private_api
There is no full php example. I'm guess somebody could put it here.
There is only snippet of php code:
$query_string = http_build_query($_POST, '', '&');
$ethalon_sign = hash_hmac("sha512", $query_string, $api_secret_key);
How to write authentication on python with hash_hmac sha512 ?
I want to extract my open orders POST https://api.comkort.com/v1/private/order/list.
My current variant is:
import hashlib
import hmac
import requests
import time
privateKey = b'myprivatekey'
publicKey = 'my public key'
url = 'https://api.comkort.com/v1/private/order/list'
tosign = b'market_alias=doge_ltc'
signing = hmac.new( privateKey , tosign, hashlib.sha512 )
headers = {'sign': signing.digest(), "apikey": publicKey, "nonce": int( time.time() ) }
r = requests.get(url, headers=headers)
print r.text
I'm caught this
{"code":401,"error":"Invalid sign","field":"sign"}
May be hexdigest() instead digest()? I don't know, I'm playing around this b prefix and different output hmac's options, everytime I'm caught one error: "Invalid sign".
Related: HMAC signing requests in Python
If somebody interesting, I've solve this by myself.
#!/usr/bin/python
import hashlib
import hmac
import requests
import time
apikey = '';
apisecret = '';
def request_comkort( url, payload ):
tosign = "&".join( [i + '=' + payload[i] for i in payload] )
sign = hmac.new( apisecret, tosign , hashlib.sha512);
headers = {'sign': sign.hexdigest(), 'nonce': int( time.time() ), 'apikey': apikey }
r = requests.post(url, data=payload, headers=headers)
return r.text
# Get balance
print request_comkort( "https://api.comkort.com/v1/private/user/balance";, {} )
# Get Open Orders
print request_comkort( "https://api.comkort.com/v1/private/order/list";, {'market_alias': "DOGE_LTC" } )
# Make Ask
print request_comkort( "https://api.comkort.com/v1/private/order/sell";, { 'market_alias':"HTML_DOGE", "amount": "1000", "price": "123123" } )
# Cancel order
print request_comkort( "https://api.comkort.com/v1/private/order/cancel";, { 'order_id': 10943 } )
I'm having an awfully hard time with Yahoo's authentication/authorization. I've enabled BOSS in my account, set up a payment method, and now I'm trying to run a search using some python code:
import urllib2
import oauth2 as oauth
import time
OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"
def oauth_request(url, params, method="GET"):
params['oauth_version'] = "1.0",
params['oauth_nonce'] = oauth.generate_nonce(),
params['oauth_timestamp'] = int(time.time())
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY,
secret=OAUTH_CONSUMER_SECRET)
params['oauth_consumer_key'] = consumer.key
req = oauth.Request(method=method, url=url, parameters=params)
req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)
return req
if __name__ == "__main__":
url = "http://yboss.yahooapis.com/ysearch/web"
req = oauth_request(url, params={"q": "cats dogs"})
req_url = req.to_url()
print req_url
result = urllib2.urlopen(req_url)
I keep getting a urllib2.HTTPError: HTTP Error 401: Unauthorized exception. I can't figure out whether there's something wrong with my key, or the method of signing, or if I'm somehow tampering with my data after signing, or what the deal is. Anyone have suggestions?
I made some small changes to make your example work. See code for comments.
import urllib2
import oauth2 as oauth
import time
OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"
def oauth_request(url, params, method="GET"):
# Removed trailing commas here - they make a difference.
params['oauth_version'] = "1.0" #,
params['oauth_nonce'] = oauth.generate_nonce() #,
params['oauth_timestamp'] = int(time.time())
consumer = oauth.Consumer(key=OAUTH_CONSUMER_KEY,
secret=OAUTH_CONSUMER_SECRET)
params['oauth_consumer_key'] = consumer.key
req = oauth.Request(method=method, url=url, parameters=params)
req.sign_request(oauth.SignatureMethod_HMAC_SHA1(), consumer, None)
return req
if __name__ == "__main__":
url = "http://yboss.yahooapis.com/ysearch/web"
req = oauth_request(url, params={"q": "cats dogs"})
# This one is a bit nasty. Apparently the BOSS API does not like
# "+" in its URLs so you have to replace "%20" manually.
# Not sure if the API should be expected to accept either.
# Not sure why to_url does not just return %20 instead...
# Also, oauth2.Request seems to store parameters as unicode and forget
# to encode to utf8 prior to percentage encoding them in its to_url
# method. However, it's handled correctly for generating signatures.
# to_url fails when query parameters contain non-ASCII characters. To
# work around, manually utf8 encode the request parameters.
req['q'] = req['q'].encode('utf8')
req_url = req.to_url().replace('+', '%20')
print req_url
result = urllib2.urlopen(req_url)
Here is a Python code snippet that works for me against Yahoo! BOSS:
import httplib2
import oauth2
import time
OAUTH_CONSUMER_KEY = "Blah"
OAUTH_CONSUMER_SECRET = "Blah"
if __name__ == "__main__":
url = "http://yboss.yahooapis.com/ysearch/web?q=cats%20dogs"
consumer = oauth2.Consumer(key=OAUTH_CONSUMER_KEY,secret=OAUTH_CONSUMER_SECRET)
params = {
'oauth_version': '1.0',
'oauth_nonce': oauth2.generate_nonce(),
'oauth_timestamp': int(time.time()),
}
oauth_request = oauth2.Request(method='GET', url=url, parameters=params)
oauth_request.sign_request(oauth2.SignatureMethod_HMAC_SHA1(), consumer, None)
oauth_header=oauth_request.to_header(realm='yahooapis.com')
# Get search results
http = httplib2.Http()
resp, content = http.request(url, 'GET', headers=oauth_header)
print resp
print content
Im using an Authenticate Header to submit the OAuth signature.
So I decided to ditch Python and try Perl, and it Just Worked. Here's a minimal code sample:
use strict;
use Net::OAuth;
use LWP::UserAgent;
my $CC_KEY = "blahblahblah";
my $CC_SECRET = "blah";
my $url = 'http://yboss.yahooapis.com/ysearch/web';
print make_request($url, {q => "cat dog", format => "xml", count => 5});
sub make_request {
my ($url, $args) = #_;
my $request = Net::OAuth->request("request token")
->new(
consumer_key => $CC_KEY,
consumer_secret => $CC_SECRET,
request_url => $url,
request_method => 'GET',
signature_method => 'HMAC-SHA1',
timestamp => time,
nonce => int(rand 10**6),
callback => 'oob',
extra_params => $args,
protocol_version => Net::OAuth::PROTOCOL_VERSION_1_0A,
);
$request->sign;
my $res = LWP::UserAgent->new(env_proxy=>1)->get($request->to_url);
return $res->content if $res->is_success;
die $res->status_line;
}
Here's another solution, this time back in python-land. This was put together by Tom De Smedt, author of the Pattern web-mining kit.
I'll communicate with the author of python-oauth2 to see if it can be fixed.
OAUTH_CONSUMER_KEY = "blahblahblah"
OAUTH_CONSUMER_SECRET = "blah"
import urllib
import hmac
import time
import random
import base64
try:
from hashlib import sha1
from hashlib import md5
except:
import sha as sha1
import md5; md5=md5.new
def hmac_sha1(key, text):
return hmac.new(key, text, sha1).digest()
def oauth_nonce(length=40):
h = "".join([str(random.randint(0, 9)) for i in range(length)])
h = md5(str(time.time()) + h).hexdigest()
return h
def oauth_timestamp():
return str(int(time.time()))
def oauth_encode(s):
return urllib.quote(s, "~")
def oauth_signature(url, data={}, method="get", secret="", token=""):
# Signature base string: http://tools.ietf.org/html/rfc5849#section-3.4.1
base = oauth_encode(method.upper()) + "&"
base += oauth_encode(url.rstrip("?")) + "&"
base += oauth_encode("&".join(["%s=%s" % (k, v) for k, v in sorted(data.items())]))
# HMAC-SHA1 signature algorithm: http://tools.ietf.org/html/rfc5849#section-3.4.2
signature = hmac_sha1(oauth_encode(secret) + "&" + token, base)
signature = base64.b64encode(signature)
return signature
q = "cat"
url = "http://yboss.yahooapis.com/ysearch/" + "web" # web | images | news
data = {
"q": q,
"start": 0,
"count": 50, # 35 for images
"format": "xml",
"oauth_version": "1.0",
"oauth_nonce" : oauth_nonce(),
"oauth_timestamp" : oauth_timestamp(),
"oauth_consumer_key" : OAUTH_CONSUMER_KEY,
"oauth_signature_method" : "HMAC-SHA1",
}
data["oauth_signature"] = oauth_signature(url, data, secret=OAUTH_CONSUMER_SECRET)
complete_url = url + "?" + urllib.urlencode(data)
response = urllib.urlopen(complete_url)
print response.read()
Here is sample code to access Yahoo! BOSS API v2 using with python-oauth as oauth liberary.
OAUTH_CONSUMER_KEY = "<oauth consumer key>"
OAUTH_CONSUMER_SECRET = "<oauth consumer secret>"
URL = "http://yboss.yahooapis.com/ysearch/web"
import urllib
import oauth.oauth as oauth
data = {
"q": "yahoo boss search",
"start":0,
"count":2,
"format":"json"
}
consumer = oauth.OAuthConsumer(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET)
signature_method_plaintext = oauth.OAuthSignatureMethod_PLAINTEXT()
signature_method_hmac_sha1 = oauth.OAuthSignatureMethod_HMAC_SHA1()
oauth_request = oauth.OAuthRequest.from_consumer_and_token(consumer, token=None, http_method='GET', http_url=URL, parameters=data)
oauth_request.sign_request(signature_method_hmac_sha1, consumer, "")
complete_url = oauth_request.to_url()
response = urllib.urlopen(complete_url)
print "REQUEST URL => %s" % complete_url
print ""
print "RESPONSE =>"
print response.read()
I stepped into the urllib2.open code using the debugger, and found that the response has this header:
WWW-Authenticate: OAuth oauth_problem="version_rejected", realm="yahooapis.com"
So I guess I'm having some kind of version mismatch of OAuth.