Authorization issue with python request [duplicate] - python

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

Related

Python: Encode Base64 to Basic connect to an API

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)

Python3: Custom Encrypted Headers URLLIB - KrakenAPI

Alright, so I'm a little outside of my league on this one I think.
I'm attempting to facilitate custom HTTP headers what is noted here:
API-Key = API key
API-Sign = Message signature using HMAC-SHA512 of (URI path + SHA256(nonce + POST data)) and base64 decoded secret API key
from https://www.kraken.com/help/api
I'm trying to work solely out of urllib if at all possible.
Below is one of many attempts to get it encoded like required:
import os
import sys
import time
import datetime
import urllib.request
import urllib.parse
import json
import hashlib
import hmac
import base64
APIKey = 'ThisKey'
secret = 'ThisSecret'
data = {}
data['nonce'] = int(time.time()*1000)
data['asset'] = 'ZUSD'
uripath = '/0/private/TradeBalance'
postdata = urllib.parse.urlencode(data)
encoded = (str(data['nonce']) + postdata).encode()
message = uripath.encode() + hashlib.sha256(encoded).digest()
signature = hmac.new(base64.b64decode(secret),
message, hashlib.sha512)
sigdigest = base64.b64encode(signature.digest())
#this is purely for checking how things are coming along.
print(sigdigest.decode())
headers = {
'API-Key': APIKey,
'API-Sign': sigdigest.decode()
}
The above may be working just fine, where I'm struggling now is appropriately getting it to the site.
This is my most recent attempt:
myBalance = urllib.urlopen('https://api.kraken.com/0/private/TradeBalance', urllib.parse.urlencode({'asset': 'ZUSD'}).encode("utf-8"), headers)
Any help is greatly appreciated.
Thanks!
urlopen doesn't support adding headers, so you need to create a Request object and pass it to urlopen:
url = 'https://api.kraken.com/0/private/TradeBalance'
body = urllib.parse.urlencode({'asset': 'ZUSD'}).encode("utf-8")
headers = {
'API-Key': APIKey,
'API-Sign': sigdigest.decode()
}
request = urllib.request.Request(url, data=body, headers=headers)
response = urllib.request.urlopen(request)

Authorization header in Requests package in python

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()

Issue with AppDynamics REST call with Python

I tried to call AppDynamics API using python requests but face an issue.
I wrote a sample code using the python client as follows...
from appd.request import AppDynamicsClient
c = AppDynamicsClient('URL','group','appd#123')
for app in c.get_applications():
print app.id, app.name
It works fine.
But if I do a simple call like the following
import requests
usr =<uid>
pwd =<pwd>
url ='http://10.201.51.40:8090/controller/rest/applications?output=JSON'
response = requests.get(url,auth=(usr,pwd))
print 'response',response
I get the following response:
response <Response [401]>
Am I doing anything wrong here ?
Couple of things:
I think the general URL format for app dynamics applications are (notice the '#'):
url ='http://10.201.51.40:8090/controller/#/rest/applications?output=JSON'
Also, I think the requests.get method needs an additional parameter for the 'account'. For instance, my auth format looks like:
auth = (_username + '#' + _account, _password)
I am able to get a right response code back with this config. Let me know if this works for you.
You could also use native python code for more control:
example:
import os
import sys
import urllib2
import base64
# if you have a proxy else comment out this line
proxy = urllib2.ProxyHandler({'https': 'proxy:port'})
opener = urllib2.build_opener(proxy)
urllib2.install_opener(opener)
username = "YOUR APPD REST API USER NAME"
password = "YOUR APPD REST API PASSWORD"
#Enter your request
request = urllib2.Request("https://yourappdendpoint/controller/rest/applications/141/events?time-range-type=BEFORE_NOW&duration-in-mins=5&event-types=ERROR,APPLICATION_ERROR,DIAGNOSTIC_SESSION&severities=ERROR")
base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)
response = urllib2.urlopen(request)
html = response.read()
This will get you the response and you can parse the XML as needed.
If you prefer it in JSON simply specify it in the request.

Tagging Jira issues with Zapier (Hiding credentials in zapier Python)

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)

Categories