madatajs / madata

Make any cloud service with an API your backend! WIP
https://madata.dev
MIT License
34 stars 3 forks source link

Support PKCE for OAuth 2.0 in our OAuthBackend class #47

Open DmitrySharabin opened 1 year ago

DmitrySharabin commented 1 year ago

Beginning working on a backend for Airtable, I faced an issue that our OAuthBackend doesn't support the authorization parameter rules, which are mandatory for Airtable.

It turned out those rules are a part of the PKCE extension of OAuth. And it looks like those rules might become a part of the backends we might decide to support in the future. So it would be nice if we could support the PKCE extension of OAuth and allow backends to opt it in.

DmitrySharabin commented 1 year ago

Here is a repo from Airtable with an example of the way they use PKCE in the auth flow: https://github.com/Airtable/oauth-example/blob/main/index.js

LeaVerou commented 1 year ago

We should definitely support this. Not sure if in the OAuthBackend or in a subclass (PKCEOAuthBackend?), it depends on how different it is from the current flow. The code you linked to is too much code to process, what are the actual differences of PKCE?

DmitrySharabin commented 1 year ago

If I understand everything correctly, we should implement the following steps by authenticating the user client-side:

  1. Generate a random string, called code verifier, 43–128 characters long.
  2. Generate a SHA256 hash of the code verifier to get a string called code challenge.
  3. Pass the code verifier and the code challenge along with other OAuth params: the code verifier should be passed as a property codeVerifier of the state object (along with the other properties, like backend and url); the code challenge should be passed as a value of the code_challenge query parameter; the code_challenge_method parameter should have the value S256.

The auth server should pass the code verifier as a query parameter when obtaining an access token. Then, the auth server should return the code verifier along with the access token so that we can compare (client-side) the returned code verifier with the one we sent and ensure the access token is not compromised.

And one more thing, the code verifier and the code challenge should contain characters from the following set:

a-z / A-Z / 0-9 / “.” / “-” / “_”

—and be Base64-encoded.

I hope my explanation makes sense.

Here is a tool that might help us get familiar with how the code verifier and the code challenge should look: https://example-app.com/pkce.