5

I am trying to access the Buxfer REST API using Python and urllib2.

The issue is I get the following response:

urllib2.HTTPError: HTTP Error 403: Forbidden

But when I try the same call through my browser, it works fine...

The script goes as follows:

username = "xxx@xxxcom"
password = "xxx"

    #############

def checkError(response):
    result = simplejson.load(response)
    response = result['response']
    if response['status'] != "OK":
        print "An error occured: %s" % response['status'].replace('ERROR: ', '')
        sys.exit(1)

    return response

base = "https://www.buxfer.com/api";
url  = base + "/login?userid=" + username + "&password=" + password;

req = urllib2.Request(url=url)
response = checkError(urllib2.urlopen(req))
token = response['token']

url  = base + "/budgets?token=" + token;
req = urllib2.Request(url=url)
response = checkError(urllib2.urlopen(req))
for budget in response['budgets']:
    print "%12s %8s %10.2f %10.2f" % (budget['name'], budget['currentPeriod'], budget['limit'], budget['remaining'])

sys.exit(0)

I also tried using the requests library but the same error appears. The server I am tring to access from is an ubuntu 14.04, any help on explaining or solving why this happens will be appreciated.

EDIT:

This is the full error message:

{                                                                                                            
  'cookies': <<class 'requests.cookies.RequestsCookieJar'>[]>,                                               
  '_content': '                                                                                              
    <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">                                                       
    <html><head>                                                                                             
    <title>403 Forbidden</title>                                                                             
    </head><body>                                                                                            
    <h1>Forbidden</h1>                                                                                       
    <p>You don't have permission to access /api/login                                                        
    on this server.</p>                                                                                      
    <hr>                                                                                                     
    <address>Apache/2.4.7 (Ubuntu) Server at www.buxfer.com Port 443</address>                               
    </body></html>',                                                                                         
  headers': CaseInsensitiveDict({                                                                            
    'date': 'Sun, 31 Jan 2016 12:06:44 GMT',                                                                 
    'content-length': '291',                                                                                 
    'content-type': 'text/html; charset=iso-8859-1',                                                         
    'server': 'Apache/2.4.7 (Ubuntu)'                                                                        
  }),                                                                                                        
  'url': u'https://www.buxfer.com/api/login?password=xxxx&userid=xxxx%40xxxx.com',                           
  'status_code': 403,                                                                                        
  '_content_consumed': True,                                                                                 
  'encoding': 'iso-8859-1',                                                                                  
  'request': <PreparedRequest [GET]>,                                                                        
  'connection': <requests.adapters.HTTPAdapter object at 0x7fc7308102d0>,                                    
  'elapsed': datetime.timedelta(0, 0, 400442),                                                               
  'raw': <urllib3.response.HTTPResponse object at 0x7fc7304d14d0>,                                           
  'reason': 'Forbidden',                                                                                     
  'history': []                                                                                              
}             

EDIT 2: (Network parameters in GoogleChrome browser)

Request Method:GET
Status Code:200 OK
Remote Address:52.20.61.39:443
Response Headers
view parsed
HTTP/1.1 200 OK
Date: Mon, 01 Feb 2016 11:01:10 GMT
Server: Apache/2.4.7 (Ubuntu)
X-Frame-Options: SAMEORIGIN
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Cache-Controle: no-cache
Set-Cookie: login=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; domain=buxfer.com
Set-Cookie: remember=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; domain=buxfer.com
Vary: Accept-Encoding
Content-Encoding: gzip
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/x-javascript; charset=utf-8
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,fr;q=0.6
Connection:keep-alive
Cookie:PHPSESSID=pjvg8la01ic64tkkfu1qmecv20; api-session=vbnbmp3sb99lqqea4q4iusd4v3; __utma=206445312.1301084386.1454066594.1454241953.1454254906.4; __utmc=206445312; __utmz=206445312.1454066594.1.1.utmcsr=google|utmccn=(organic)|utmcmd=organic|utmctr=(not%20provided)
Host:www.buxfer.com
Upgrade-Insecure-Requests:1
User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36

EDIT 3:

I can also access through my local pycharm console without any issues, it's just when I try to do it from my remote server...

johan855
  • 1,578
  • 4
  • 26
  • 51
  • Can you post the full error message? Which request results in the 403? Do you get the token? – Håken Lid Jan 31 '16 at 12:17
  • When I create an account on buxfer, your code runs perfectly for me. I am running Python 2.7.6 on Ubuntu 14.04.3. – Robᵩ Jan 31 '16 at 12:22
  • Hey Rob, do you have a /var/www folder? I've seen in a cuple of forums some API require this folder to exist for a callback process – johan855 Jan 31 '16 at 12:24
  • Are you using a real username and password? From the error message it just looks like you use a invalid user. 403 Forbidden would not be surprising. – Håken Lid Jan 31 '16 at 15:44
  • I am, I am using the same url created in the script on my web browser and I get access. – johan855 Jan 31 '16 at 17:17

2 Answers2

2

It could be that you need to do a POST rather than a GET request. Most logins work this way.

Using the requests library, you would need

response = requests.post(
    base + '/login',
    data={
        'userid': username,
        'password': password
    }
)
Carl
  • 1,027
  • 1
  • 9
  • 21
  • Hi Carl, thanks for your time, I just tried using POST but the error is still the same – johan855 Jan 31 '16 at 12:24
  • @johan855 Can you look at the Network tab in the developer console of your browser (Chrome and Firefox both have this), go through the login process, and look at what information get sent to the server and how. Is a POST or a GET, is it form encoded or JSON encoded, or something else, what are the parameters and their values (there might be some hidden fields), etc. That should provide all information needed to log in with a script. – Carl Feb 01 '16 at 08:49
  • Hi Carl, I added the results to the question, but i am afraid this doesn't contain anything I previously didn't know, request is a GET and response is JSON encoded, no additional prompts or forms after i navigate to the url – johan855 Feb 01 '16 at 11:05
  • @johan855 I can't tell whether the `urllib2` code will maintain the cookies sent back by the server. Based on your Chrome output, there are definitely some important login-related cookies returned. You can try to check that. If you're will to move over to `requests` I can try to help some more, since it is a lot better at maintaining requests state (including cookies). – Carl Feb 01 '16 at 15:59
  • Yes I definitely agree on moving onto requests, I just used urllib2 since it is what their API example suggests. One thing I also tried was sendind with the request the header: User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.97 Safari/537.36 but no luck... – johan855 Feb 01 '16 at 16:01
0

To affirm @Carl from the offical website:

This command only looks at POST parameters and discards GET parameters.

https://www.buxfer.com/help/api#login

carrvo
  • 511
  • 5
  • 11