简体   繁体   中英

Base64 Encoding issue - Python vs Powershell

I am trying to encode an auth token and pass it to a REST API, this works fine with powershell but applying the same method to python script throws 'unauthorized' exception.

I suspect there is a problem in encoded value. Not able to figure out the solution. Any ideas ?

The rest endpoint is IBM uDeploy.

Powershell

$tokenEncoded = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes( "PasswordIsAuthToken:{`"token`":`"$pass`"}" ))
$basicAuthValue = "Basic $tokenEncoded"
$headers = @{}
$headers.Add("Authorization", $basicAuthValue)
$response = Invoke-RestMethod -Method Put -Headers $headers -Uri $requestUri -Body $jsonRequest

Python

epass = base64.b64encode("PasswordIsAuthToken:{\"token\":\"$password\"}")
print 'base64 encoded: ' + epass
opener = urllib2.build_opener(urllib2.HTTPHandler)
req = urllib2.Request(reqUrl,json.dumps(json_data))
req.add_header('Authorization', 'Basic '+epass)
req.get_method = lambda: 'PUT'
resp = opener.open(req)

You are sending the literal string $password as the token, not the contents of a variable named password .

You only need to include the PasswordIsAuthToken and your token in a Basic Auth HTTP header ( PasswordIsAuthToken forms the username, and token the password):

epass = base64.b64encode("PasswordIsAuthToken:" + password)
opener = urllib2.build_opener(urllib2.HTTPHandler)
req = urllib2.Request(reqUrl,json.dumps(json_data))
req.add_header('Authorization', 'Basic ' + epass)

If you reall need to wrap the token in a JSON-like structure then you'd need to use string formatting (which the Powershell code also does, but you omitted):

epass = base64.b64encode('PasswordIsAuthToken:{"token":"%s"}' % password)

or you could use the json module:

epass = base64.b64encode('PasswordIsAuthToken:' + json.dumps({'token': password}))

However, I believe the system should accept the token unwrapped.

I strongly recommend you use the requests library instead, which makes using a REST API vastly cleaner:

import requests

auth = ('PasswordIsAuthToken', password)
# or alternatively
# auth = ('PasswordIsAuthToken', '{"token":"%s"}' % password)
response = requests.put(json=json_data, auth=auth)

Note that there is no need to encode the JSON body yourself, nor do you have to encode the Basic Auth header.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM