Receiving 403 Redirect URI Mismatch from /oauth/authorize when App is already authorized

Description
We cannot use /oauth/authorize+/oauth/token to re-authorize our Zoom app (called Bookwhen) when it’s already installed: instead we are told “Redirect URI mismatch” with code 403 Forbidden.

Found a previous issue that was solved via DMs: "Invalid request : Redirect URI mismatch." - #12 by will.zoom

From that issue:

A few more things to check on:

  • Can you confirm you’ve updated your Whitelist URLs each time you’ve started up your ngrok server?
  • Can you try double encoding your redirect URL
  • Can you confirm your redirect URL doesn’t contain any query params

Yes to all three: whitelist URLs are correct; double-encoding caused an error on /oauth/authorize; redirect url has no query params.

Error
{"reason": "Invalid request : Redirect URI mismatch", "error": "invalid_request"}

Which App Type (OAuth / Chatbot / JWT / Webhook)?
OAuth (via Ruby’s OAuth2::Client gem oauth2 | RubyGems.org | your community gem host)

Which Endpoint/s?
/oauth/authorize
/oauth/token

How To Reproduce (If applicable)
Steps to reproduce the behavior:

  1. Request GET https://zoom.us/oauth/authorize?client_id=g6EknL_KSm6zy9BOHNnc6Q&redirect_uri=https%3A%2F%2Fbookwhen.test%2Fintegrations%2Fzoom%2Foauth%2Fcallback&response_type=code (my testing app called bookwhen-test)
  2. Authorize the app for the logged-in Zoom user: response returns 200 with authorization code
  3. Request POST https://zoom.us/oauth/token with {"redirect_uri":"https://bookwhen.test/integrations/zoom/oauth/callback","grant_type":"authorization_code","headers":{"Authorization":"Basic [encoded client ID + secret key]"}}
  4. Response returns 200 with access+refresh token
  5. Repeat steps 1+2: response returns 200 with authorization code
  6. Repeat steps 3+4: response returns 403 with “Redirect URI mismatch”

Additional context
We are already successfully using /oauth/authorize to authorize for our users, and with the code returned we are able to successfully fetch and store an access+refresh token and make requests on behalf of the user.

Making that exact same /oauth/authorize + /oauth/token request again, with the same parameters and everything, results in 403 Forbidden because Redirect URI mismatch.

If we fail to save the refresh token that’s returned in every request, then we need to ask our users to re-authorize, but they can’t because of this error. The only solution is to uninstall our app and authorize, which causes all the meetings we created to be deleted. After successfully installing the app from scratch, we then recreate all those meetings, and hit the “100 requests per day per app” rate limit, which means we can’t perform our responsibilities for our users for 24 hours.

Thanks for your help,
Henry

Hey @bookwhen

Thanks for posting on the Zoom Devforum! I am still learning, but I will try my best to help answer your question. :slightly_smiling_face:

Checkout this related thread that may have the answer you are looking for:

If this thread did not help, please let us know by replying back here and someone from the Developer Relations team will get back to you shortly.

Thanks,
DeveloperBot

No, that related thread did not help.

Nevermind, figured it out: we weren’t sending the redirect_uri with the /oauth/token requests.

Turns out Zoom allows the first /oauth/token request with an authorisation code for an installed app to succeed without the redirect_uri: it will return an access+refresh token. Every subsequent request with an authorisation code however must include the redirect_uri or 403 Redirect URI mismatch error will be returned.

This was confusing us to no end, because we were making subsequent “Request Access Token” requests in exactly the same way regardless if the app was installed/authorised on Zoom or not.

If this isn’t fixed in Zoom’s OAuth implementation, I think it should be mentioned in the docs: https://marketplace.zoom.us/docs/guides/auth/oauth

Hey @bookwhen,

Thank you for reaching out to the Zoom Developer Forum. I’m glad to hear that you were able to resolve your issue! I’ll talk with our documentation about making the requirement for the redirect_uri more explicit.

As always, please feel free to reach out if you encounter any further issues or questions.

Thanks,
Max