Python Authentication :)

Highlighted
New Member
24 0 0
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.
0 Likes
Shopify Staff
Shopify Staff
2045 0 40

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
0 Likes
New Member
24 0 0

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

0 Likes
Shopify Staff
Shopify Staff
2045 0 40

+1 ;-)

Tobias Lütke - Shopify CEO // http://twitter.com/tobi
0 Likes
New Member
1 0 0

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

0 Likes
New Member
1 0 0

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.

0 Likes
Shopify Staff
Shopify Staff
49 0 1

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

Developer
0 Likes