# Zoom OAuth 2.0 Proof Key for Code Exchange (PKCE) Flow

**URL:** <https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830>\
**Category:** API and Webhooks\
**Tags:** faq, oauth, pkce-flow, guide, pkce\
**Created:** [February 5, 2022, 1:22am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830 "2022-02-05T01:22:04Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [February 5, 2022, 1:22am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/1 "2022-02-05T01:22:04Z")

</div>

# Summary

Zoom supports Proof of Key Code Exchange (PKCE), pronounced “Pixy”, industry _-_ standard protocol for authorization when requesting user tokens. This offers better security by enabling clients to use a code challenge and code exchange as part of the initial user authorization request. See [rfc7636](https://tools.ietf.org/html/rfc7636) for details.

# What is PKCE?

PKCE is an extension to the OAuth 2 spec. Its design aims to add an additional layer of security that verifies that the authentication and token exchange requests come from the same client. This is achieved through the use of the `code_challenge` and `code_verifier` parameters, sent by the third-party application during the OAuth process.

🎯 The `code_verifier` parameter’s value uses the [SHA 256](https://www.movable-type.co.uk/scripts/sha256.html) Cryptographic Hash Algorithm. SHA 256 creates a unique “signature” for a text or file of any size,

🎯 The `code_challenge` [Base64-encodes](https://www.base64encode.org/) the value generated from the code\_verifer step.

# ⚠ Note:

- Regardless of the input file or text, the generated value is always the same length

- Guaranteed to be always produce the same result for the same input

- One way (that is, you can’t reverse engineer it to reveal the original input)

- Code\_challenge value should be equivalent to the `code_verifier` parameter’s value when using the “plain” code challenge mode, or a cryptographic hash of the `code_verifier` parameters’ value, though the use of the “plain” code challenge method is largely discouraged.

# Generate the Code\_verifier and Code\_challenge:

👟 You can manually generate the **code\_verifier** by entering a random string into the **SHA256 online tool** on Github:

> **[SHA256](https://emn178.github.io/online-tools/sha256.html)**
>
> This SHA256 online tool helps you calculate hashes from strings. You can input UTF-8, UTF-16, Hex, Base64, or other encodings. It also supports HMAC.

### SHA256 Tool Screenshot:

 ![ShA256](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/0/3/03e9bb201d1c847ee453bd54e98b6d6802445a3f.png)

👟 Then, manually encode the encrypted value with the **Base64 online tool** :

> **[Base64 Encode and Decode - Online](https://www.base64encode.org)**
>
> Encode to Base64 format or decode from it with various advanced options. Our site has an easy to use online tool to convert your data.

### Base64encode Tool Screenshot:

 ![Encode_to_base64](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/9/6/9648cd15b4f1773d73d9a88c69b9349d0b2d83f3.png)

### Programmatically generate the **Code\_verifier** and **Code\_challenge**

Alternatively, you can programmatically generate the **Code\_verifier** and **Code\_challenge** with the following script:

```auto
mkdir crypto-gen
cd crypto-gen
npm init -y

```

```auto

const crypto = require("crypto");
const btoa = require('btoa');

function base64URLEncode(str) {
    return str.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}

function sha256_ASCII(buffer) {
  return crypto.createHash('sha256').update(buffer).digest('base64').toString("ascii");
}

const code_Verifier = base64URLEncode(crypto.randomBytes(32));
const code_ChallengeUrlSafeEncode = base64URLEncode(sha256_ASCII(code_Verifier));

console.log("code_verifier: " + code_Verifier);

# Append trailing "=" to the end code_challenge_url_safe_encode
console.log("URL safe encode code_challenge : " + code_ChallengeUrlSafeEncode + "=");

```

# PKCE Flow Overview

🎯 During the initial step ( `https://zoom.us/oauth/authorize` ) of the OAuth procedure, the `code_challenge` parameter is provided by the third-party client to the OAuth provider.

🎯 After the user has manually authorized the application, the OAuth provider should then respond with an authorization code, which must be returned to the OAuth provider along with the `code_verifier` parameter, by the third-party client, in exchange for an access token.

🎯 If the `code_verifier` parameter does not match the `code_challenge` provided by the client in the initial authorization request, this may indicate an attempted code injection attack, and so the OAuth process should be abandoned by the provider and an error returned to the third-party client.

🎯 If Zoom verifies that the `code_challenge` and the `code_verifier` match, the token endpoint ([https://zoom.us/oauth/token](https://zoom.us/oauth/token)) continues processing.

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [February 5, 2022, 1:52am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/2 "2022-02-05T01:52:45Z")

</div>

# Zoom OAuth 2.0 PKCE Flow: In Postman

### Step 1: [Getting an Access Token](https://marketplace.zoom.us/docs/guides/auth/oauth/#getting-an-access-token)

A. Direct the user to `https://zoom.us/oauth/authorize` with the following query parameters:

 ![Screen Shot 2022-02-05 at 12.06.16 AM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/7/d/7d6b8924b0f73b089819cb19cef0e189e95e8a15.png)

### Postman Authorization Tab Configuration:

1. Under the **Authorization** tab of any request, select `OAuth 2.0`.Select **Get New Access Token**.

2. From there, select a **Grant Type** of **Authorization Code (With PKCE)**, and click **Authorize using the browser** checkbox.

3. In the **Auth URL** field, enter **Zoom Authorization** endpoint with **response\_type** and **code\_challenge** params values included:

4. In the **Access Token URL** field, enter the access token endpoint

5. In the **clientID** field, enter Zoom Marketplace OAuth app **clientID**.

6. In the **Code Challenge Method** field, select **SHA-256** and click **Get New Access token.**

7. Postman will open a browser tab that redirects to the endpoint entered for the [Zoom Marketplace redirect URL](https://marketplace.zoom.us/docs/guides/build/oauth-app#oauth-allow-list). Appended to the end of the Redirect URL, you will find the Authorization Code, which must be returned to the OAuth provider (Zoom) to get **Access Token**. This example leverages Postman’s redirect endpoint ([https://oauth.pstmn.io/v1/callback](https://oauth.pstmn.io/v1/callback)):

 ![image](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/4/3/43408b6a65cee213b7e542f1b6109ee42495b45e.png)

### Postman Authorization Tab:

Here is a screenshot of what the populated **Authorization tab** looks like:

 ![Screen Shot 2022-02-04 at 8.31.27 PM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/8/b/8bfcc2e1ec53b89e6b74e7494e27a5bb4b61b238.png)

### Step 2: [Request Access Token](https://marketplace.zoom.us/docs/guides/auth/oauth#step-2-request-access-token):

A. Create Post to [https://zoom.us/oauth/token](https://zoom.us/oauth/token) with the following headers and query parameters:

 ![Screen Shot 2022-02-04 at 9.06.59 PM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/d/f/df99977414d759d2a4857189bb878d30d7477dd7.png)

### Postman Params Tab Configuration :

1. On the Postman **Params Tab** , set **code** , **grant\_type** , **redirect\_url** , and **code\_verifer** param values:

 ![Get Access Token Post Request](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/5/b/5b32a3f7a83586410672d4e3deef282ccacd4b5f.png)

1. On the Postman **Headers Tab** , set **Content-Type** and **Authorization** headers, then click Send:

 ![Screen Shot 2022-02-04 at 9.10.27 PM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/7/0/70cd9feef2f53e1430919988512de4863ddca219.png)

For reference, here is a video demonstrating the PKCE Flow:

(Coming Soon)

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [February 5, 2022, 1:54am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/3 "2022-02-05T01:54:44Z")

</div>

# 📚 Resources

## 🌟 [OAuth with Zoom Help Documentation](https://marketplace.zoom.us/docs/guides/auth/oauth)

> **[RFC 7636: Proof Key for Code Exchange by OAuth Public Clients](https://datatracker.ietf.org/doc/html/rfc7636)**
>
> OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack. This specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key...

---

<div class="post-metadata">

**Author:** ![Danz](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/danz/32/8497_2.png) [@Danz](https://devforum.zoom.us/u/Danz)\
**Post date:** [February 8, 2022, 3:59am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/4 "2022-02-08T03:59:54Z")

</div>

PKCE will be enforced in May 2022. Is there a way to enforce this sooner for an app, so that the PKCE enhancements can be checked so we can be absolutely sure that when the May 2022 switch over occurs, we’re good. I have checked the app settings in our test apps and can’t find a way to enforce PKCE and the form encoded token requests, and so although we have coded and tested the changes, we are not able to see the effect of toggling the enforcement, so we are left to assume our changes will just work.

---

<div class="post-metadata">

**Author:** ![smurray](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/smurray/32/19830_2.png) [@smurray](https://devforum.zoom.us/u/smurray)\
**Post date:** [February 16, 2022, 12:46am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/5 "2022-02-16T00:46:24Z")

</div>

Also looking at this as well. Will this be able to be tested?

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [February 16, 2022, 1:01am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/6 "2022-02-16T01:01:01Z")

</div>

Greeting@Danz & @smurray,

Thank you both for this question. Let me check internally, and I’ll let you know what I learn.

Best,  
Donte

---

<div class="post-metadata">

**Author:** ![smurray](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/smurray/32/19830_2.png) [@smurray](https://devforum.zoom.us/u/smurray)\
**Post date:** [February 18, 2022, 12:20am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/7 "2022-02-18T00:20:46Z")

</div>

Thanks. Can you also check your code sample. It seems to be producing a code\_challenge that doesn’t line up with most other implementations in industry.

I think the place where it diverges is with the `btoa(...)` call which produces a code\_challenge that is different than other algorithms do. This threw me off for a while.

See: [javascript - Creating a code verifier and challenge for PKCE auth on Spotify API in ReactJS - Stack Overflow](https://stackoverflow.com/a/63336562)

Also a good resource for others looking at this. A PKCE validator/generator:

[https://example-app.com/pkce](https://example-app.com/pkce)

UPDATE–

After some more testing, it seems that only your implementation above seems to work with the OAuth flow. If you try any other standard implementation to get a code\_challenge from a code\_verifier, they all fail on authentication with an `invalid_grant` response but if I use your code above (which produces different code\_challenge results). I can successfully do PKCE auth flow. Can you give some guidance on this? It seems you are using a non-standard implementation.  
@donte.S ?

---

<div class="post-metadata">

**Author:** ![smurray](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/smurray/32/19830_2.png) [@smurray](https://devforum.zoom.us/u/smurray)\
**Post date:** [February 21, 2022, 7:46pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/8 "2022-02-21T19:46:21Z")

</div>

@Danz I don’t know if you have seen this but it looks like if you send the `code_challenge` with the initial auth request, it enforces that you have the correct `code_verifier` on the token request. So you can test out your implementation now. They just don’t enforce it yet. It will at least give you confidence that your solution works.

---

<div class="post-metadata">

**Author:** ![Danz](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/danz/32/8497_2.png) [@Danz](https://devforum.zoom.us/u/Danz)\
**Post date:** [February 21, 2022, 8:11pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/9 "2022-02-21T20:11:25Z")

</div>

@smurray agreed and we’ve implemented it and have seen behaviour to indicate that this is all being processed and our solution works. However, we don’t have the peace of mind of having tested the situation when they flip the switch. So, we are left to assume we’ll be good rather than know for sure.

---

<div class="post-metadata">

**Author:** ![smurray](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/smurray/32/19830_2.png) [@smurray](https://devforum.zoom.us/u/smurray)\
**Post date:** [February 22, 2022, 12:32am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/10 "2022-02-22T00:32:15Z")

</div>

Hey @donte.zoom

I dug a little more into getting this working for us and it seems that the core of the issue with your (Zoom’s) implementation of PKCE vs. other API providers who are implementing this is here:

`const code_challenge = btoa(sha256(code_verifier));`

`sha256(code_verifier)` returns a string object in javascript so then the input to this:  
`btoa(hashed_code_verifier)` is a string as well. This leads to the resulting output being twice as long (64 bytes/characters if you start with a 32 byte `code_verifier`) than what other implementations are doing. The rest produce the same size `code_challenge` as `code_verifier`.

I imagine for anyone using javascript/NodeJS this isn’t much of a problem because they can just copy your code. Since our code is in C# (and any other language like it, Java, C++ will have to make the same adjustment) I had to write some extra coding to get your result.

Example that works with Zoom’s current implementation where a **32** bit `code_verifier` produces a **64** bit `code_challenge` due to the `byte[]` → `string` conversion that happens.

```auto
public static string GetZoomCodeChallengeFromVerifier(string codeVerifier)
{
    string codeChallenge = string.Empty;
    using (SHA256 sha = SHA256.Create())
    {
        var bytes = Encoding.UTF8.GetBytes(codeVerifier);
        var hash = sha.ComputeHash(bytes);

        // Here is where Zoom goes out into left field due to their Javascript implementation
        // they do this:
        // code_challenge = btoa(sha256(code_verifier))
        // so that the type passed to btoa is a string representation of the hash,
        // not a byte representation
        // So the input is roughtly twice as long
        // so btoa() makes a longer string that is base 64 encoded
        // So we have to follow and covert the hash from bytes to a string to match the behavior
        string hashString = BitConverter.ToString(hash).Replace("-", "").ToLower();
        byte[] bytesNew = Encoding.GetEncoding(28591).GetBytes(hashString);
        codeChallenge = System.Convert.ToBase64String(bytesNew);
    }

    return codeChallenge;
}

```

Example of what common practice seems to be elsewhere to produce the `code_challenge`. For example a **32** bit `code_verifier` produces a **32** bit `code_challenge`

```auto
public static string GetZoomCodeChallengeFromVerifier(string codeVerifier)
{
    string codeChallenge = string.Empty;
    using (SHA256 sha = SHA256.Create())
    {
        var bytes = Encoding.UTF8.GetBytes(codeVerifier);
        byte[] hash = sha.ComputeHash(bytes);
        // Here the hash is taken in directly as a byte array
        codeChallenge = System.Convert.ToBase64String(hash);
    }

    return codeChallenge;
}

```

The [OAuth.com PKCE page](https://auth0.com/docs/get-started/authentication-and-authorization-flow/call-your-api-using-the-authorization-code-flow-with-pkce) gives the following javascript implementation to produce the `code_challenge`. This lines up with other examples I have seen:

```auto
// Dependency: Node.js crypto module
// https://nodejs.org/api/crypto.html#crypto_crypto
function sha256(buffer) {
    return crypto.createHash('sha256').update(buffer).digest();
}
var challenge = base64URLEncode(sha256(verifier));

```

As an example. The following shows what happens with a given `code_verifier` and results of Zoom’s implementation and [OAuth.com](http://OAuth.com)’s one.

```auto
code_verifier: OoRepCjjX8P4perVeWHK-5TKSfyZLPuCjirkjY3hh7I
Zoom's code_challenge: YWRmMTUyNGZkODZlMDFiMTI4ZTQ1M2Y0NzExYWNkNWJjZDc2NWU2ZTRjMDYxMWVjYmJiZmZhMmNkYzRhOWYyOA==
OAuth's code_challenge: rfFST9huAbEo5FP0cRrNW812Xm5MBhHsu7_6LNxKnyg

```

Can you speak the the difference in what the [OAuth.com](http://OAuth.com) page itself recommends and why your implementation is different and produces different results?

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [February 22, 2022, 7:06pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/11 "2022-02-22T19:06:49Z")

</div>

@smurray,

Thanks for letting us know about your situation. You’re right! The current implementation does not follow other API providers’ implementation. I can understand that it’s frustrating to have to make adjustments to your code to get the expected code\_challenge result. Our engineers are aware of this and are making plans to make changes to better align with a more consistent PKCE flow standard. For now, the javascript/Nodejs above can serve as an implementation reference for completing the PKCE flow.

Thanks again for taking the time to talk to us! I appreciate your feedback on this matter, and I’ll be sure to keep you updated. You can also stay up-to-date with any new or upcoming features, by following our [changelog](https://marketplace.zoom.us/docs/changelog) and [upcoming changes](https://marketplace.zoom.us/docs/guides/stay-up-to-date/announcements) pages.

Best,  
Donte

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [February 23, 2022, 10:49pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/12 "2022-02-23T22:49:39Z")

</div>

@Danz & @smurray,

> [@Danz](#):
>
> PKCE will be enforced in May 2022

As a follow-up, it looks like the Zoom OAuth Security requirement will be pushed back to a later date. The date has not been set yet, however, I will provide another update when it is published.

Warm Regards,  
Donte

---

<div class="post-metadata">

**Author:** ![smurray](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/smurray/32/19830_2.png) [@smurray](https://devforum.zoom.us/u/smurray)\
**Post date:** [February 23, 2022, 11:22pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/13 "2022-02-23T23:22:16Z")

</div>

Thanks @donte.zoom

So to confirm, May 2022 is no longer the date when PKCE will be enforced and it will be some later date?

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [February 24, 2022, 12:47am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/14 "2022-02-24T00:47:59Z")

</div>

Correct, @smurray! The May 2022 date is under review and will likely no longer be when PKCE is enforced. A new date hasn’t been set at the moment. However, I will provide another update as soon as it is.

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [March 7, 2022, 6:40pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/15 "2022-03-07T18:40:01Z")

</div>

@smurray & @Danz,

Please see the updated notice on Zoom OAuth Security Update.

## [Zoom OAuth Security Updates Link](https://marketplace.zoom.us/docs/guides/stay-up-to-date/announcements#zoom-oauth-security-updates)

 ![Screen Shot 2022-03-07 at 1.37.03 PM](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/e/1/e1eda3b56a0fcff2f349d25b16279503528094eb.png)

With Care,  
Donte

---

<div class="post-metadata">

**Author:** ![Danz](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/danz/32/8497_2.png) [@Danz](https://devforum.zoom.us/u/Danz)\
**Post date:** [March 7, 2022, 8:33pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/16 "2022-03-07T20:33:55Z")

</div>

Thank you for drawing our attention to this I appreciate it!

---

<div class="post-metadata">

**Author:** ![donte.zoom](https://sea2.discourse-cdn.com/flex016/user_avatar/devforum.zoom.us/donte.zoom/32/24412_2.png) [@donte.zoom](https://devforum.zoom.us/u/donte.zoom)\
**Post date:** [March 7, 2022, 9:12pm UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/17 "2022-03-07T21:12:30Z")

</div>

My pleasure @Danz!

With Care,  
Donte

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex016/uploads/zoomdeveloper/original/3X/6/1/614bdd549b610bbaa46ff934617683a02bdaa03c.png) [@system](https://devforum.zoom.us/u/system)\
**Post date:** [April 7, 2022, 7:13am UTC](https://devforum.zoom.us/t/zoom-oauth-2-0-proof-key-for-code-exchange-pkce-flow/63830/18 "2022-04-07T07:13:20Z")

</div>

Closed on April 7, 2022, 7:13am UTC

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
