Twitter OAuth authentication giving a 401 error - python

import requests
import secrets
import time
import hmac
import base64
from hashlib import sha1
from urllib.parse import quote_plus
from src.config import API_KEY, ACCESS_TOKEN, API_KEY_SECRET, ACCESS_TOKEN_SECRET
def get_oauth_params():
oauth_nonce = secrets.token_hex(16)
oauth_consumer_key = API_KEY
oauth_signature_method = "HMAC-SHA1"
oauth_timestamp = str(int(time.time()))
oauth_version = "1.0"
oauth_token = ACCESS_TOKEN
oauth_params = {
"oauth_nonce": oauth_nonce,
"oauth_consumer_key": oauth_consumer_key,
"oauth_signature_method": oauth_signature_method,
"oauth_timestamp": oauth_timestamp,
"oauth_version": oauth_version,
"oauth_token": oauth_token
}
return oauth_params
def get_signature(signature_base_string, signing_key):
signature_base_string_bytes = bytes(signature_base_string,'ascii')
signing_key_bytes = bytes(signing_key,'ascii')
hashed = hmac.new(signing_key_bytes, signature_base_string_bytes, sha1)
hashed_bytes = hashed.digest()
b64_bytes = base64.b64encode(hashed_bytes)
b64_signature = quote_plus(b64_bytes.decode('ascii')).rstrip("\n");
return b64_signature
def make_auth_request(url, callback_url):
oauth_params = get_oauth_params()
parameter_string = f"oauth_callback={callback_url}&oauth_consumer_key={oauth_params['oauth_consumer_key']}&oauth_nonce={oauth_params['oauth_nonce']}&oauth_signature_method={oauth_params['oauth_signature_method']}&oauth_timestamp={oauth_params['oauth_timestamp']}&oauth_token={oauth_params['oauth_token']}&oauth_version={oauth_params['oauth_version']}"
percent_encoded_parameter_string = quote_plus(parameter_string)
percent_encoded_url = quote_plus(url)
signature_base_string = f"POST&{percent_encoded_url}&{percent_encoded_parameter_string}"
signing_key = quote_plus(API_KEY_SECRET) + "&" + quote_plus(ACCESS_TOKEN_SECRET)
oauth_signature = get_signature(signature_base_string, signing_key)
percent_encoded_callback_url = quote_plus(callback_url)
headers = {
"Accept": "*/*",
"Connection": "close",
"Content-Type": "application/x-www-form-urlencoded",
"Authorization": f"OAuth oauth_callback=\"{percent_encoded_callback_url}\",oauth_consumer_key=\"{oauth_params['oauth_consumer_key']}\",oauth_nonce=\"{oauth_params['oauth_nonce']}\",oauth_signature=\"{oauth_signature}\",oauth_signature_method=\"{oauth_params['oauth_signature_method']}\",oauth_timestamp=\"{oauth_params['oauth_timestamp']}\",oauth_token=\"{oauth_params['oauth_token']}\",oauth_version=\"{oauth_params['oauth_version']}\"",
}
print(headers["Authorization"])
r = requests.post(url, headers=headers)
print(r.status_code)
r_json = r.json()
return r_json
if __name__ == '__main__':
r_json = make_auth_request("https://api.twitter.com/oauth/request_token", "https://crunchftw.github.io")
print(r_json)
I want to implement login with twitter, for that i first have to get the oauth token by a POST request to https://api.twitter.com/oauth/request_token with the oauth signature. I think I've implemented everything correctly. The paramenter string and oauth Authorization strings are in order. But Twitter is sending back an error
401 {'errors': [{'code': 32, 'message': 'Could not authenticate you.'}]}
Could someone please help?
I used this Twitter Website for creating the signature https://developer.twitter.com/en/docs/authentication/oauth-1-0a/creating-a-signature

Related

How to get user details after login via oauth?

Trying to understand how it works oauth
How to get authorized user details using Blizzard api?
import json
import requests
client_id = ""
client_secret = ""
region = "eu"
data = {
'grant_type': 'client_credentials'
}
access_token_response = requests.post(f"https://{region}.battle.net/oauth/token", data=data, allow_redirects=False, auth=(client_id, client_secret))
access_token = json.loads(access_token_response.text)["access_token"]
api_call_headers = {
'Authorization': 'Bearer ' + access_token
}
api_call_response = requests.get(f"https://{region}.battle.net/oauth/userinfo", headers=api_call_headers)

Trying to retrieve data from the Anbima API

I'm trying to automate a process in which i have to download some brazilian fund quotes from Anbima (Brazil regulator). I have been able to work around the first steps to retrieve the access token but i don't know how to use the token in order to make requests. Here is the tutorial website https://developers.anbima.com.br/en/como-acessar-nossas-apis/.
I have tried a lot of thing but all i get from the request is 'Could not find a required APP in the request, identified by HEADER client_id.'
If someone could share some light. Thank you in advance.
import requests
import base64
import json
requests.get("https://api.anbima.com.br/feed/fundos/v1/fundos")
ClientID = '2Xy1ey11****'
ClientSecret = 'faStF1Hc****'
codeString = ClientID + ":" + ClientSecret
codeStringBytes = codeString.encode('ascii')
base64CodeBytes = base64.b64encode(codeStringBytes)
base64CodeString = base64CodeBytes.decode('ascii')
url = "https://api.anbima.com.br/oauth/access-token"
headers = {
'content-type': 'application/json'
,'authorization': f'Basic {base64CodeString}'
}
body = {
"grant_type": "client_credentials"
}
r = requests.post(url=url, data=json.dumps(body), headers=headers, allow_redirects=True)
jsonDict = r.json()
##################
urlFundos = "https://api-sandbox.anbima.com.br/feed/precos-indices/v1/titulos-publicos/mercado-secundario-TPF"
token = jsonDict['access_token']
headers2 = {
'content-type': 'application/json'
,'authorization': f'Bearer {token}'
}
r2 = requests.get(url=urlFundos, headers=headers2)
r2.status_code
r2.text
I was having the same problem, but today I could advance. I believe you need to adjust some parameters in the header.
Follows the piece of code I developed.
from bs4 import BeautifulSoup
import requests
PRODUCTION_URL = 'https://api.anbima.com.br'
SANDBOX_URL = 'https://api-sandbox.anbima.com.br'
API_URL = '/feed/fundos/v1/fundos/'
CODIGO_FUNDO = '594733'
PRODUCTION = False
if PRODUCTION:
URL = PRODUCTION_URL
else:
URL = SANDBOX_URL
URL = URL + API_URL + CODIGO_FUNDO
HEADER = {'access_token': 'your token',
'client_id' : 'your client ID'}
html = requests.get(URL, headers=HEADER).content
soup = BeautifulSoup(html, 'html.parser')
print(soup.prettify())
The sandbox API will return a dummy JSON. To access the production API you will need to request access (I'm trying to do this just now).
url = 'https://api.anbima.com.br/oauth/access-token'
http = 'https://api-sandbox.anbima.com.br/feed/precos-indices/v1/titulos-publicos/pu-intradiario'
client_id = "oLRa*******"
client_secret = "6U2nefG*****"
client_credentials = "oLRa*******:6U2nefG*****"
client_credentials = client_credentials.encode('ascii')
senhabytes = base64.b64encode(client_credentials)
senha = base64.b64decode(senhabytes)
print(senhabytes, senha)
body = {
"grant_type": "client_credentials"
}
headers = {
'content-type': 'application/json',
'Authorization': 'Basic b0xSYTJFSUlOMWR*********************'
}
request = requests.post(url, headers=headers, json=body, allow_redirects=True)
informacoes = request.json()
token = informacoes['access_token']
headers2 = {
"content-type": "application/json",
"client_id": f"{client_id}",
"access_token": f"{token}"
}
titulos = requests.get(http, headers=headers2)
titulos = fundos.json()
I used your code as a model, then I've made some changes. I've printed the encode client_id:client_secret and then I've copied and pasted in the headers.
I've changed the data for json.

Cannot close trade successfully with Oanda Api

I am using the following code for request:
import requests
import print
import json
api_key = "XXX-XXX"
api_version = 'v3'
accountID = "XXX"
tradeID = "XX"
#Endpoint Parts
api_base_url = f"https://api-fxpractice.oanda.com/"
key_url = f"https://api-fxpractice.oanda.com/v3/accounts"
headers = {
'Authorization': f'bearer {api_key}',
'Content-Type': 'application/json'
}
data = {'units': 'ALL'}
endpoint_path = f"/{api_version}/accounts/{accountID}/trades/{tradeID}/close"
endpoint = f"{api_base_url}{endpoint_path}"
r = requests.put(endpoint, headers=headers, data=data)
print(r.status_code)
pprint.pprint(r.json())
Response I get:
400
{'errorMessage': "Invalid value specified for 'Authorization'"}

Kuna Code activation error by API, how to solve?

Good day!
I am trying to use the API of the Kuna.io exchange
There is a method in the documentation: /v3/auth/kuna_codes/redeem
I get the error:
{"messages": ["signature_is_incorrect"]}
Works correctly with other methods
import requests
import time
import hmac
import hashlib
url = "https://api.kuna.io/v3/auth/kuna_codes/redeem"
api_path = "/v3/auth/kuna_codes/redeem"
secret_key = 'key'
public_key = 'key'
nonce = str(int(time.time()*1000.0))
body = str('')
msg = api_path+nonce+body
kun_signature = hmac.new(secret_key.encode('ascii'), msg.encode('ascii'), hashlib.sha384).hexdigest()
payload = {"code": "ZC7Xr-TBcfa-DW3hg-xNUr8-cxnp2-CHada-QT9Yr-L14DZ-5pyjA-UAH-KCode"}
headers = {
"Accept": "application/json",
"Content-Type": "application/json",
'kun-nonce': nonce,
'kun-apikey': public_key,
'kun-signature': kun_signature,
}
response = requests.request("PUT", url, json=payload, headers=headers)
print(response.text)
My suspicions are that the method is wrong since the signature works correctly with other methods.
The signature should contain a body. Try with this one
payload = {"code": "ZC7Xr-TBcfa-DW3hg-xNUr8-cxnp2-CHada-QT9Yr-L14DZ-5pyjA-UAH-KCode"}
body = json.dumps(payload)
msg = api_path+nonce+body

converting python oauth to postman request

I am trying to convert successful python (flask) OAuth 2.0 authentication / api request into Postman.
My current process is:
From the front end, I hit an /auth endpoint in python using fetch:
fetch("/auth")
.then(function (response) {
return response.json();
})
.then(function (json) {
const code = json.code;
window.location = `[hostname.com]/auth/authorize?request_token=${code}&redirect_uri=http://[hostname]/menu`;
});
The backend flask auth endpoint looks like this:
url = 'https://[hostname].com/v3/oauth/request'
headers = CaseInsensitiveDict()
headers['Host'] = '[hostname].com'
headers['Content-Type'] = 'application/json'
headers['X-Accept'] = 'application/json'
data = json.dumps({'consumer_key': 'XXXX', 'redirect_uri':'[hostname]/success'})
resp = requests.post(url, headers=headers, data=data)
json_resp = json.loads(resp.content)
auth_code = json_resp['code']
auth_resp = {'code': auth_code}
return jsonify(auth_resp)
The access endpoint takes that auth code to get the token
cur_auth = session.get('auth_code',None)
url = 'https://[hostname.com]/v3/oauth/authorize'
headers = CaseInsensitiveDict()
headers['Host'] = '[hostname].com'
headers['Content-Type'] = 'application/json; charset=UTF-8'
headers['X-Accept'] = 'application/json'
data = json.dumps({'consumer_key': 'XXXX', 'code': cur_auth})
resp = requests.post(url, headers=headers, data=data)
json_resp = resp.json()
access_token = json_resp['access_token']
username = json_resp['username']
session['access_token']=access_token
session['username']=username
access_resp = {'access': access_token, 'user': username}
return jsonify(access_resp)
But when I try to translate this into a postman request, I can't really understand where some of the things like the consumer_key request_token and code get defined.
I'm currently getting a 400 bad request with this setup:
where the consumer_key is in Postman's client secret field, and where
https://[hostname].com/v3/oauth/request is in Postman's auth field and
https://getpocket.com/v3/oauth/authorize is in Postman's access token url field.

Categories

Resources