129

I'm trying to use basic HTTP authentication in Python. I am using the Requests library:

auth = requests.post('http://' + hostname, auth=HTTPBasicAuth(user, password))
request = requests.get('http://' + hostname + '/rest/applications')

Response form auth variable:

<<class 'requests.cookies.RequestsCookieJar'>[<Cookie JSESSIONID=cb10906c6219c07f887dff5312fb for appdynamics/controller>]>
200
CaseInsensitiveDict({'content-encoding': 'gzip', 'x-powered-by': 'JSP/2.2', 'transfer-encoding': 'chunked', 'set-cookie': 'JSESSIONID=cb10906c6219c07f887dff5312fb; Path=/controller; HttpOnly', 'expires': 'Wed, 05 Nov 2014 19:03:37 GMT', 'server': 'nginx/1.1.19', 'connection': 'keep-alive', 'pragma': 'no-cache', 'cache-control': 'max-age=78000', 'date': 'Tue, 04 Nov 2014 21:23:37 GMT', 'content-type': 'text/html;charset=ISO-8859-1'})

But when I try to get data from different location, I'm getting HTTP Status 401 error:

<<class 'requests.cookies.RequestsCookieJar'>[]>
401
CaseInsensitiveDict({'content-length': '1073', 'x-powered-by': 'Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.2.2 Java/Oracle Corporation/1.7)', 'expires': 'Thu, 01 Jan 1970 00:00:00 UTC', 'server': 'nginx/1.1.19', 'connection': 'keep-alive', 'pragma': 'No-cache', 'cache-control': 'no-cache', 'date': 'Tue, 04 Nov 2014 21:23:37 GMT', 'content-type': 'text/html', 'www-authenticate': 'Basic realm="controller_realm"'})

As far as I understand, in the second request session parameters are not substituted.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
oleksii
  • 1,367
  • 2
  • 10
  • 11

6 Answers6

134

You need to use a session object and send the authentication each request. The session will also track cookies for you:

session = requests.Session()
session.auth = (user, password)

auth = session.post('http://' + hostname)
response = session.get('http://' + hostname + '/rest/applications')
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 4
    Thanks for your reply, but it's doesn't work too :( Error is the same as previous – oleksii Nov 05 '14 at 00:01
  • 1
    @oleksii: define 'does not work'. And when you use POST (with no parameters, I note), does the server return any token or anything that you'd need to use for the REST API here? In other words, what does the *documentation for the API* state you need to do? – Martijn Pieters Nov 05 '14 at 08:38
  • @Sarit how so? Note that I link to the official documentation in my answer. – Martijn Pieters Jan 08 '18 at 08:22
  • @MartijnPieters Sorry I was taking about this page http://docs.python-requests.org/en/master/user/authentication/ – joe Jan 08 '18 at 08:37
  • @Sarit that page deals with all different forms of HTTP authentication. Cluttering it with session handling would cloud matters. Not all use cases need to make multiple HTTP requests, and you can get the same effect by passing in the auth info manually with every request. – Martijn Pieters Jan 08 '18 at 08:43
  • 2
    @MartijnPieters After read your comment 10th fimes. I still not understand. I can use basicAuth in the Postman. Postman will digest username/password into header `Authorization: Basic <....>`. But I could not be able to connect why I need session here, but it works! What's wrong with @oleksii attempt? – joe Jan 08 '18 at 09:17
  • 4
    @Sarit: The header needs to be included in *every request* that you send to the server; usually the only way the server can authenticate you based on the header being present, no other info. The *easiest* way to add the header to every request is to use a session. You don't *have* to, but then you have to include the header manually in each request. – Martijn Pieters Jan 08 '18 at 11:58
98
import requests

from requests.auth import HTTPBasicAuth
res = requests.post('https://api.github.com/user', auth=HTTPBasicAuth('user', 'password'))
print(res)
Daniel Darabos
  • 26,991
  • 10
  • 102
  • 114
Kuppuram
  • 997
  • 6
  • 3
  • 2
    ```requests.posts``` does not work for me but ```requests.get``` does, there is also a shorter version ```requests.get(url, auth=(username, password))``` – Marcin Kulik Dec 14 '20 at 09:37
  • 3
    This doesn't answer the question, which is about using the session cookie to authenticate subsequent requests. – wim Oct 11 '22 at 21:10
44

In Python3 it becomes easy:

import requests
response = requests.get(uri, auth=(user, password))
3

Below one worked for me

#!/usr/bin/python3
import xml.etree.ElementTree as ET
import requests
from requests.auth import HTTPBasicAuth

url = 'http://172.25.38.135:600/service/xx/users'      # my URL     
response = requests.get(url, auth=HTTPBasicAuth('admin', 'adminpass!'))

string_xml = response.content
tree = ET.fromstring(string_xml)
ET.dump(tree)
Anto
  • 3,128
  • 1
  • 20
  • 20
  • 2
    This doesn't answer the question, which is about using the session cookie to authenticate subsequent requests. – wim Oct 11 '22 at 21:10
1

for python 2:

base64string = base64.encodestring('%s:%s' % (username, password)).replace('\n', '')

request = urllib2.Request(url)

request.add_header("Authorization", "Basic %s" % base64string) 

result = urllib2.urlopen(request)
        data = result.read()
Aaron
  • 2,367
  • 3
  • 25
  • 33
vc2310
  • 131
  • 1
  • 1
  • 7
  • 1
    This doesn't answer the question, which is about using the session cookie to authenticate subsequent requests. – wim Oct 11 '22 at 21:11
-1

The following worked for me

from requests.auth import HTTPDigestAuth
url = 'https://someserver.com'
requests.get(url, auth=HTTPDigestAuth('user', 'pass'))
codeaprendiz
  • 2,703
  • 1
  • 25
  • 49