I’m trying to use the SDK’s `OAuthAuthenticator` t...
# singer-tap-development
p
I’m trying to use the SDK’s
OAuthAuthenticator
to authenticate with the PayPal API and am running into some trouble. The API expects a request for an access token that looks like this if using curl
Copy code
curl -v <https://api-m.sandbox.paypal.com/v1/oauth2/token> \
  -H "Accept: application/json" \
  -H "Accept-Language: en_US" \
  -u "client_id:secret" \
  -d "grant_type=client_credentials"
How do I replicate that with the oauth authenticator class? I tried using the
client_id
and
client_secret
properties and also tried setting the client ID and secret in the
username
and
password
params in
oauth_request_body()
but both returned a forbidden error
i’m also able to successfully fetch an access token just with requests like this
Copy code
<http://requests.post|requests.post>(URL, auth=("<client_id>", "<client_secret>"), data={"grant_type": "client_credentials"})
s
can you override the
oauth_request_body
property to return `{"grant_type": "client_credentials"}`and perahps overwrite the
auth_header
property to get what you need? https://gitlab.com/meltano/sdk/-/blob/main/singer_sdk/authenticators.py#L422
it looks like your header might need to be a base64 encoded
client_id:secret
?
I haven't used this OAuth authenticator before, just guessing
p
i might be misunderstanding but are you suggesting something like this? that doesn’t seem to work either
s
yeah, that's what i was thinking 😕
p
Welp @aaronsteers any ideas?
a
Hi @prratek_ramchandani - I think I may be able to shed some light on this. As you pointed out, when you follow the PayPal guide the end result of the OAuth flow is a Bearer access token. You use this in the http Authorization header e.g.
Copy code
-H "Authorization: Bearer [your token]" \
https://developer.paypal.com/docs/api/reference/get-an-access-token/ As you also pointed out, to get the Bearer access token requires Basic Auth request:
Copy code
curl -v <https://api-m.sandbox.paypal.com/v1/oauth2/token> \
  -H "Accept: application/json" \
  -H "Accept-Language: en_US" \
  -u "client_id:secret" \
  -d "grant_type=client_credentials"
However, the Singer SDK base class for OAuthAuthenticator expects to help you construct an unauthenticated POST request - which would be similar to the following in curl
Copy code
curl -v <https://api-m.sandbox.paypal.com/v1/oauth2/token> \
  -H "Accept: application/json" \
  -H "Accept-Language: en_US" \
  -d "{'grant_type':[your client_credentials], 'client_id':[your client id], 'secret': [your secret]}"
https://gitlab.com/meltano/sdk/-/blob/main/singer_sdk/authenticators.py#L351 I think this means you need to roll your own Authenticator, or create a MR to get this into the SDK! For your own Authenticator you will extend what you started with 
Copy code
<http://requests.post|requests.post>(URL, auth=("<client_id>", "<client_secret>"), data={"grant_type": "client_credentials"})
The Basic Authorization header is 'Basic ' followed by a BASE64 encoded string e.g.
Copy code
-H "Authorization: Basic [base64 encoded 'client_id:secret']" \
p
ooh thank you! i would not have picked up on that distinction - i’ll write my own authenticator