d
Topic
jmorrin Member
Posts:
24
June 07, 2009

Python Authentication :) This post is outdated

So I am having some issues logging in and using the api. I can use the api with curl no problem: curl -u API:PASS http://some-shop.myshopify.com/admin/collects.xml and I get back the xml for the collections!!!! Awesome right, well kinda :) So I am trying to use python to build my app, but I keep getting an authentication required error while using urllib2. I have setup my HTTPPasswordMgrWithDefaultRealm and it just fails to authenticate. So I did a little digging and constructed the http header on my own with the base64 encoded string from curl. (captured with a proxy) Authentication worked! So I tried to just base64 encode my api key and secret with base64.encodestring and for some reason there are '\n' in my encoded string. If I remove the newlines it will authenticate. I have no idea why this is happening I did some digging around the internet and found nothing. I figured I would just post here my findings so if anyone else is using python they won't waste an afternoon doing something that should be simple :) I have read the python documentation on base64 and they mention the encoded string ending in \n but I am finding them in the string. I bet this is why urllib2 won't work with the password manager.
i
Replies
Posts:
2056
June 10, 2009

Very strange. We use totally standard HTTP Authentication. You are right, this is based on base64 but you shouldn’t have to do this manually, the library should really be able to do this.

Tobias Lütke - Shopify CEO // http://twitter.com/tobi
jmorrin Member
Posts:
24
June 10, 2009

No I am not blaming shopify, just figured I would post it here incase someone else came across it.

Its documented that the library will add a \n at the end of the base64 encoded string, but I am getting them in the middle of the string too..

Oh well, guess I should really be using Ruby anyway :)

Posts:
2056
June 10, 2009

+1 ;-)

Tobias Lütke - Shopify CEO // http://twitter.com/tobi
Sidi Mohamed Member
Posts:
1
September 06, 2009

Hi,

You can use headers to do authentication :

import urllib2, base64

request = urllib2.Request(URL)
base64string = base64.encodestring('%s:%s' % (KEY, PASSWORD)).replace('\n', '')
request.add_header("Authorization", "Basic %s" % base64string)   
result = urllib2.urlopen(request)

It works fine !

Hope that will help you :)

mdorns Member
Posts:
1
Last edited September 20, 2009

The Python Libraries urllib2 and httplib2 both first send an unauthenticated request and if this is answered with a 401 response the libs retry with the correct credentials. I’m not sure why this design was chosen, but it may make sense if you use the same “HTTP-Object” to connect to many different hosts/realms/URLs.

The Problem is it seems to me, that Shopify doesn’t really “use totally standard HTTP Authentication”. The HTTP-Standard RfC 2616 reads:

10.4.2 401 Unauthorized
The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource.

My debugging indicates that Shopify doesn’t send a “WWW-Authenticate” Header in it’s response. Therefore the libs don’t try further authentication – which is at least according to the spec reasonable.

Dennis Theisen Shopify
Posts:
46
September 21, 2009

Wow mdorns, that was indeed a very good find that slipped through our testing!

We will add the WWW-Authenticate header for unauthenticated API requests in our next big deployment!

Thanks a lot for your comment, that was very helpful!

Cheers, Dennis

Shopify Support Developer

Log in or sign up for an account to reply.

This thread has been closed! You will not be able to reply.