Potential Workaround for Proof Key for Code Exchange (PKCE) OAuth 2.0

  • 23 January 2023
  • 0 replies
  • 66 views

Userlevel 1
Badge +1

IMPORTANT UPDATE (March 23, 2023)


Support for PKCE is now available in version 14.0.0 (CHANGELOG) of the Zapier Developer Platform. This workaround is no longer necessary and should be replaced by an implementation that uses official support:


Hello there! 👋 As some of you may already have discovered, the Zapier Developer Platform supports the OAuth 2.0 "Authorization Code Flow" but it does not currently have support for the PKCE extension to OAuth 2.0.

We do have PKCE support on our roadmap but we aren’t able to offer a timeline on that. To help any developers blocked by this we wanted to share a potential workaround with you. It can be implemented in both Platform UI (Visual Builder) and CLI apps. Please read on for more details!

Before Starting

Before giving this workaround a try, please first check that the API you’re using sends back the `state` parameter value (generated by Zapier) along with the authorization code parameter value after authentication is successful, i.e. in the `redirect_url` "callback", as per (C) in the diagram below:

Source: https://datatracker.ietf.org/doc/html/rfc6749#section-4.1

Important: if the API does not send back the `state` parameter value this workaround will not work.

Step 1 - Create a "salt"

1. Create a randomly generated "salt"

Create a randomly generated string of between 20 and 105 characters in length to use as the "salt". You could run the node crypto `randomBytes()` function locally to do this or use a random password or salt generator of your choice.

2. Create a new Environment Variable
Create a new environment variable (Visual Builder / CLI) named `PKCE_SALT` and add the randomly generated "salt" value to it.

Example:

Step 2 - Modify the Login Request

Add code to the "Authorization URL" settings in Authentication

If you're using the the Visual Builder, switch to "Code Mode" on the "Authorization URL" section in "Authentication" and add the following code to:

  1. Require the node `crypto` module
  2. Create a `code_verifier`: a combination of the randomly generated `state` and `PKCE_SALT`
  3. Create a `code_challenge`: a hashed version of `code_verifier`
  4. Send the `code_challenge` and any other additional PKCE related values as request parameters

 

Sample Code

const crypto = z.require("crypto");
const code_verifier = bundle.inputData.state + process.env.PKCE_SALT;

const code_challenge = crypto
.createHash("sha256")
.update(code_verifier)
.digest("base64url");

const url = `https://accounts.spotify.com/authorize?
client_id=${process.env.CLIENT_ID}
&state=${bundle.inputData.state}
&redirect_uri=${encodeURIComponent(bundle.inputData.redirect_uri)}
&response_type=code
&code_challenge_method=S256
&code_challenge=${code_challenge}`;

return url;

Notes:

  • CLI: add this code to the `authorizeUrl` method.

Step 3 - Modify the Token Request

Add code to the "Access Token Request" settings in Authentication

If you're using the Visual Builder, switch to "Code Mode" on the "Access Token Request" section in "Authentication" and add the following code to include the `code_verifier` as a request parameter:

Sample Code

'code_verifier': bundle.cleanedRequest.querystring.state + process.env.PKCE_SALT

Notes:

  • Reminder: code_verifier is a combination of the randomly generated state and PKCE_SALT
  • Visual Builder: make sure you click the “Save & Continue” button to save the changes from Step 2 and 3
  • CLI: add this code to the getAccessToken method.

Step 4 - Testing & Troubleshooting

Test the modified authentication settings to see whether the workaround is successful. If you encounter any errors or the authentication is not successful, the details of both the `authorizeUrl` and `getAccessToken` requests and responses can be reviewed on the Monitoring page of your app to perform troubleshooting.

If the workaround isn’t successful and it’s not clear why after you’ve performed the troubleshooting steps above, please submit a new support ticket from https://developer.zapier.com/contact so we can assist.

Considerations

  1. In this workaround implementation the `code_verifier` is combination of a) `state` - which contains a randomly generated number that changes on each authentication connection attempt, and b) `PKCE_SALT` - which is randomly generated but which does not change.
  2. As per the details in the “Before Starting” section, some (non-compliant) API OAuth 2.0 implementations do not return the `state` parameter value.
  3. The sample code in this workaround uses Spotify's API for illustrative purposes. However, the same approach should work with other API’s that follow RFC 7636.

This post has been closed for comments. Please create a new post if you need help or have a question about this topic.