I'm trying to connect to an API and I've to encode64 the username and password. The 'Authorisation' value should look like this: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ
When I try to connect I get an error: 'Unauthorized: Bad credentials'. The support says that my credentials are ok, but they are slow to respond to solve my issue.
I suspect the encoding part of the code, but I'm not sure. Could you please take a look at my code and tell me what could be wrong with it?
The direct link to the section about authentication in the documentation :
http://developer.outbrain.com/home-page/amplify-api/documentation/#/reference/authentications/via-api
m = str(base64.b64encode(b'xxxxx:xxxxxxx'))
headers = {
'Authorization': 'Basic ' + m + ''
}
r = requests.get('https://api.outbrain.com/amplify/v0.1/login', headers=headers)
print(r.json())
You need to use decode to correctly get a string from the byte sequence:
Wrong (note the 'b' prefix and single quotes in the result):
>>> str(base64.b64encode(b'test'))
"b'dGVzdA=='"
Right:
>>> base64.b64encode(b'test').decode('utf-8')
'dGVzdA=='
Additionally, requests can do this for you:
from requests.auth import HTTPBasicAuth
r = requests.get('https://api.outbrain.com/amplify/v0.1/login', auth=HTTPBasicAuth('user', 'pass'))
Another way to do it:
import base64
message = "user:password"
message_bytes = message.encode('ascii')
base64_bytes = base64.b64encode(message_bytes)
base64_message = base64_bytes.decode('ascii')
print(base64_message)
Related
I'm following an api and I need to use a Base64 authentication of my User Id and password.
'User ID and Password need to both be concatenated and then Base64 encoded'
it then shows the example
'userid:password'
It then proceeds to say 'Provide the encoded value in an "Authorization Header"'
'for example: Authorization: BASIC {Base64-encoded value}'
How do I write this into a python api request?
z = requests.post(url, data=zdata )
Thanks
The requests library has Basic Auth support and will encode it for you automatically. You can test it out by running the following in a python repl
from requests.auth import HTTPBasicAuth
r = requests.post(api_URL, auth=HTTPBasicAuth('user', 'pass'), data=payload)
You can confirm this encoding by typing the following.
r.request.headers['Authorization']
outputs:
u'Basic c2RhZG1pbmlzdHJhdG9yOiFTRG0wMDY4'
You can encode the data and make the request by doing the following:
import requests, base64
usrPass = "userid:password"
b64Val = base64.b64encode(usrPass)
r=requests.post(api_URL,
headers={"Authorization": "Basic %s" % b64Val},
data=payload)
I'm not sure if you've to add the "BASIC" word in the Authorization field or not. If you provide the API link, It'd be more clear.
With python3, I have found a solution which is working for me:
import base64
userpass = username + ':' + password
encoded_u = base64.b64encode(userpass.encode()).decode()
headers = {"Authorization" : "Basic %s" % encoded_u}
To explain let's use interpreter:
>>> import base64
>>> userpass = "usrname:pass"
>>> print(base64.b64encode(userpass.encode()).decode())
dXNybmFtZTpwYXNzn #That is fine b64 string
>>> print(base64.b64encode(userpass.encode()))
b'dXNybmFtZTpwYXNz' #this is byte code
>>> print(base64.b64encode(userpass))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python#3.10/3.10.7/Frameworks. /Python.framework/Versions/3.10/lib/python3.10/base64.py", line 58, in b64encode
encoded = binascii.b2a_base64(s, newline=False)
TypeError: a bytes-like object is required, not 'str'
You can see that base64.b64encode requires byte type and return bytetype so we have to use builtin decode() and encode() https://www.programiz.com/python-programming/methods/string/encode func to give the bytecode and to get the string again
As explained in the Requests documentation https://2.python-requests.org/en/latest/user/authentication/
Making requests with HTTP Basic Auth is very simple:
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
<Response [200]>
In fact, HTTP Basic Auth is so common that Requests provides a handy shorthand for using it:
>>> requests.get('https://api.github.com/user', auth=('user', 'pass'))
<Response [200]>
Providing the credentials in a tuple like this is exactly the same as
the HTTPBasicAuth example above.
I found "basicauth" package, it really made my that day. Using pip we can install.
pip install basicauth
Example client side code:
from flask import request
import basicauth
username = request.form['username']
passwd = request.form['password']
encoded_creds = basicauth.encode(username, passwd)
headers = {
"Authorization": "{0}".format(encoded_creds) # Replaces as "Authorization": "Basic WdfV0Adh4Kdf="
}
r = requests.post("http://10.0.0.1:8008/login"), headers=headers)
res = r.json()
print(res)
Example server side code
import basicauth
from flask import request
authorization = request.headers.get('Authorization')
if authorization is not None and "Basic " in authorization:
username, passwd = basicauth.decode(authorization)
print(username, passwd)
In python3, the data needs to be encoded:
import requests, base64
headers = {"Authorization": f"Basic {base64.b64encode(b'userid:password').decode()}"}
requests.post(url, headers=headers, data={})
I recommend to use:
import request
auth = ('username', 'password')
r = requests.post(url, auth=auth)
Or
import request
from requests.auth import HTTPBasicAuth
auth = HTTPBasicAuth('username', 'password')
r = requests.post(url, auth=auth)
https://2.python-requests.org/en/master/user/authentication/#basic-authentication
Writing a bot for a personal project, and the Bittrex api refuses to validate my content hash. I've tried everything I can think of and all the suggestions from similar questions, but nothing has worked so far. Tried hashing 'None', tried a blank string, tried the currency symbol, tried the whole uri, tried the command & balance, tried a few other things that also didn't work. Reformatted the request a few times (bytes/string/dict), still nothing.
Documentation says to hash the request body (which seems synonymous with payload in similar questions about making transactions through the api), but it's a simple get/chcek balance request with no payload.
Problem is, I get a 'BITTREX ERROR: INVALID CONTENT HASH' response when I run it.
Any help would be greatly appreciated, this feels like a simple problem but it's been frustrating the hell out of me. I am very new to python, but the rest of the bot went very well, which makes it extra frustrating that I can't hook it up to my account :/
import hashlib
import hmac
import json
import os
import time
import requests
import sys
# Base Variables
Base_Url = 'https://api.bittrex.com/v3'
APIkey = os.environ.get('B_Key')
secret = os.environ.get('S_B_Key')
timestamp = str(int(time.time() * 1000))
command = 'balances'
method = 'GET'
currency = 'USD'
uri = Base_Url + '/' + command + '/' + currency
payload = ''
print(payload) # Payload Check
# Hashes Payload
content = json.dumps(payload, separators=(',', ':'))
content_hash = hashlib.sha512(bytes(json.dumps(content), "utf-8")).hexdigest()
print(content_hash)
# Presign
presign = (timestamp + uri + method + str(content_hash) + '')
print(presign)
# Create Signature
message = f'{timestamp}{uri}{method}{content_hash}'
sign = hmac.new(secret.encode('utf-8'), message.encode('utf-8'),
hashlib.sha512).hexdigest()
print(sign)
headers = {
'Api-Key': APIkey,
'Api-Timestamp': timestamp,
'Api-Signature': sign,
'Api-Content-Hash': content_hash
}
print(headers)
req = requests.get(uri, json=payload, headers=headers)
tracker_1 = "Tracker 1: Response =" + str(req)
print(tracker_1)
res = req.json()
if req.ok is False:
print('bullshit error #1')
print("Bittex response: %s" % res['code'], file=sys.stderr)
I can see two main problems:
You are serialising/encoding the payload separately for the hash (with json.dumps and then bytes) and for the request (with the json=payload parameter to request.get). You don't have any way of knowing how the requests library will format your data, and if even one byte is different you will get a different hash. It is better to convert your data to bytes first, and then use the same bytes for the hash and for the request body.
GET requests do not normally have a body (see this answer for more details), so it might be that the API is ignoring the payload you are sending. You should check the API docs to see if you really need to send a request body with GET requests.
sorry for the noob question, but I think I am doing something wrong. So the idea is to fetch the json data of a Wordpress post and then print only the text content of the wp post. I am using the following setup:
url = "../wp-json/wp/v2/posts/{id}"
user= ""
password = ""
credentials = user + ':' + password
token = base64.b64encode (credentials.encode ())
header = {'Authorization': 'Basic ' + token.decode ('utf-8')}
responce = requests.get (url, headers=header, params="title")
return (responce.text)
I need it to be a string to use it within a label, but I am probably doing this wrong, any advice will be highly appreciated ^^
Not entirely sure if this is what you're looking, but if you want a string, you could try something like this:
return (str(responce))
Your first problem is:
url = "../wp-json/wp/v2/posts/{id}"
That is a relative URL, and for requests you need an absolute URL. So either provide an absolute URL or you can compute it with the following by providing your current URL, for example:
from urllib.parse import urljoin
current_url = "https://www.example.com/abc/def/x.py"
print(urljoin(current_url, "../wp-json/wp/v2/posts/{id}"))
Prints:
https://www.example.com/abc/wp-json/wp/v2/posts/{id}
Second, resonce.text will return a bytes (Python 3). If you want the content returned as a string (unicode), then return responce.content. You haven't said exactly what your problem is except "you need it as a string", so I assume this is your other problem.
I used :
return str(json.loads(responce.text))
and it worked great ^^
I am trying write a python script using requests package to use an online mongodb query service API hosted within the organization. The API expects the authorization header in the format 'websitename/username:Password' and using the basic authentication base64 encoding. I tried to create the GET request using the requests package which has the authorization header in the following format:
import requests
headers = {'Authorization': 'Basic %s' % 'Base64encoded
websitename/username:Password string here'}
content_res = requests.get(get_url, headers = headers).json()
But I am getting a parse error here for the string as I think the expected string for header in requests package is in form of 'username:password' here and not the desired format i.e. 'websitename/username:password'.
Is there a way in which I could use the base64 encoded sting in the format which the service is expecting i.e. 'websitename/username:password' in requests package?
Any help is highly appreciated.
Thanks.
It sounds to me like you are getting a HTTP response error because the authorization header value you are passing is not base64 encoded. To correct this you can simply encode the string using the base64 python module:
Python 2.7 https://docs.python.org/2/library/base64.html
Python 3.5 https://docs.python.org/3.5/library/base64.html
An example would be something like this:
import base64
import requests
website = 'example.com'
username = 'root'
password = '1234'
auth_str = '%s/%s:%s' % (website, username, password)
b64_auth_str = base64.b64encode(auth_str)
headers = {'Authorization': 'Basic %s' % b64_auth_str}
content_res = requests.get(get_url, headers=headers).json()
import base64
import requests
website = 'example.com'
username = 'root'
password = '1234'
auth_str = '%s/%s:%s' % (website, username, password)
b64_auth_str = base64.b64encode(auth_str.encode('ascii'))
headers = {'Authorization': 'Basic %s' % b64_auth_str}
content_res = requests.get(get_url, headers=headers).json()
We have Jira authenticated to Zapier, but it does not have tagging functionality, so I hacked up a simple python module below. However, it doesn't seem that I can reuse the already authenticated Jira account. Is there a way to hide the password somehow so it's not just clear text?
# jira_label and jira_url come from upstream zaps
# declaring output hash with defaults set
output = {'jira_label': jira_label}
### Python code
import requests
user = 'my_personal_user'
dpass = 'xxx' # <--- gotta do something about it
url1 = jira_url
pdata = '{"fields": {"labels": ["' + jira_label +'"]}}'
header1 = {'Content-Type': 'application/json'}
r = requests.put(url2, auth=(user, dpass), data=pdata, headers=header1)
Please use, Base64 encoding :
>>> import base64
>>> print base64.b64encode("mypassword")
bXlwYXNzd29yZA==
>>> print base64.b64decode("bXlwYXNzd29yZA==")
mypassword
With this your request will look like this:
r = requests.put(url2, auth=(user, base64.b64decode("bXlwYXNzd29yZA==")), data=pdata, headers=header1)