News & Announcements User Community Developer Community

Welcome to the RingCentral Community

Please note the community is currently under maintenance and is read-only.

Make sure to review our Terms of Use and Community Guidelines.
  Please note the community is currently under maintenance and is read-only.
Home » Developers
Browser Javascript OAuth2 PKCE: SDK throwing "code_verifier required"
Tags: sdk, oauth2
Feb 15, 2022 at 1:24pm   •   6 replies  •  0 likes
David S

Hi all. Newbie to RC here, so perhaps I am doing something wrong. But...

In a browser (Firefox) using javascript and the RC js SDK, I am trying to implement the OAuth2 3 legged flow using PKCE and "top frame setup" (see Top frame setup on the JS SDK page). FYI I have successfully implemented the "Popup setup" described on the same page.

In the Top frame setup, when my redirectUri landing page calls rcsdk.login(loginOptions) the SDK throws an error with message "code_verifier required". It looks to me like the SDK is not sending the code_verifier when making the authorization_code request to the RC Auth server and so the RC Auth servers response is a 400 bad request.

I am not sure how the SDK would know the value of the code_verifier as I believe it was generated on the main page when the loginUrl was created and I don't see how in this scenario the landing page SDK is going to have that info. So, perhaps PKCE is not possible using the top frame setup?

I have attached in a zip including simplified versions of the main page and redirectUri page html/js for your viewing pleasure.

Any advice or insight would be appreciated.

Thanks. -- David

on Feb 15, 2022 at 10:49pm   •  0 likes

A small suggestion.
Pushing your code on github/bitbucket/gitlab or any such platform and sharing the link would be more helpful for us instead of attaching a zip with the code

5 Answers
answered on Feb 17, 2022 at 8:50pm  

This is part of the SDK readme now

Thanks, @David S for helping us identify this

answered on Feb 16, 2022 at 9:02am  

On further analysis, I found the root cause
This is happening because you are creating a new instance of the SDK on the redirect page.
If you can share the same instance of SDK from the index.html and the redirect page, things will work
The SDK will save code_verifier when making the login call
can be seen here

but because on the redirect page, a new SDK instance is used, it does not know what was the code_verifier

Hope this helps

answered on Feb 16, 2022 at 9:27am  

Hi again.

Ok, so in the main page, I was able to get the code_verifier from rcsdk and save it to the browser local storage. Then in the redirect page, I was able to read the cv, add it to the loginOptions and call login(). Once login() resolved, I reloaded the main page and when I clicked the login button, it found we were already logged in and no OAuth was needed :-). Of course, you can have the redirect page reload the main page and the main page could also try to log in automagically. But I leave that as an exercise for the reader.

Updated code is here on Github as a gist.

BTW, It would be good if RC added some info about PKCE to the JS SDK page.

Thanks to Yatin for the time and comments.

on Feb 16, 2022 at 10:38am   •  0 likes

Thanks for sharing the code and details
Glad to be able to help :)

answered on Feb 16, 2022 at 7:44am  

Hi Yatin.

Thank you for taking the time to look at my question and posting a reply. I tried your suggestion and the redirectUri.html page received an error that opener is null on SDK.ts 57. That is b/c the flow I am implementing (as described on the JS SDK page) is the 'Top frame setup' not the 'Popup setup'. So on the original web app page (call it Page1), instead of getting the loginUrl and then calling loginWindow() (as is done for the Popup setup) this flow gets the loginUrl and then *navigates* to the loginUrl using the same browser window. So there is no popup or new page and thus there is no window.opener since, by design, we navigated away from Page1 to the loginUrl instead of opening a popup or new tab.

In the Popup setup (as I am sure you know), the only thing handleLoginRedirect() does is perform a postMessage() to the window.opener passing back the query params so that the call to loginWindow() resolves and Page1 can call login() passing the returned loginOptions. Login() will add the code_verifier (if set) to the token request. As I mentioned, I have implemented the Popup setup successfully, but for various reasons thought the Top frame setup might be more useful in my situation.

In the 'Top frame setup', if we weren't using PKCE, I think the redirectUri should do a login and then reload Page1 which will likely try to login to RC again and be successful (I think) since the access and refresh tokens will be stored in the browser local storage. But with PKCE we created the code verifier and code challenge in Page1 and so the redirectUri.html does not have it.

Hmm, so I am thinking that Page1, after creating the code verifier and code challenge must save the verifier to the browsers local storage. Then, in the redirectUri page, we must read the verifier and pass that to login (looks like it can be passed). Once the login is resolved, we can redirect to Page1 which will try to login to RC and find we are logged in - I hope.

But, unfortunately, I do not have access to the code_verifier (do I?) as it is embedded in the SDK.

Thanks again for your suggestion, it helped me dig deeper into things.

-- David

on Feb 16, 2022 at 8:05am   •  0 likes

Hi @David S
This is interesting.
Sorry for missing out on the use case.
I now understand what you are trying to do.
Let me try to run this locally and see if I can find the cause and the solution to this.
I am glad you went through the SDK and saw how we post internally over the socket.

I will get back on this once I try this out
Please revert with the solution if you are able to find that in the meanwhile so that it can help others looking for a similar thing :)

on Feb 16, 2022 at 8:13am   •  0 likes

Hi Yatin. No worries.

I was just able to do what I was thinking -- get the code_verifier from the rcsdk after the loginUrl is created and save it to the browsers local storage. Then in the redirectUri read the cv from localstorage, save it into the loginOptions object and pass to login(). That had a clean result. Then when I reloaded Page1 it found we were already logged in and did not need to do any OAuth. :-)

I will post the code (once cleaned up) - to github as you suggested.

on Feb 16, 2022 at 8:56am   •  0 likes

To summarize,

1. You are able to generate the login URL
2. Reach the ringcentral auth service on the top window
3. Log yourself in
4. Get a code (since you are not using implicit flow) generated on the redirect url route

Where things fail is when the SDK uses this code to make grant_type: authorization_code request to the token endpoint, it fails since code_verifier is not attached and sent for this login call

I am looking into the SDK to see if there is a bug there and maybe fix it

Like you said, the way to make to work right now will be something like

rcsdk.login({...loginOptions, code_verifier: SAVED_CODE_VERIFIER_FROM_THE_TOP_WINDOW})
on Feb 16, 2022 at 9:37am   •  0 likes

Your summarization is correct.

I don't think there is a bug in the SDK.

I am guessing most use the popup setup and this top frame setup is probably not the usual. I may not use it myself as there are some other complexities in my setup wrt subdomains. But at least now I have the option.

You could consider doing what I did, but in the SDK by saving the cv to local storage and then trying to read it again (if the class copy is empty). That would encapsulate what I did within the SDK. You could add some 'flag' passed into loginUrl() to denote this need.

answered on Feb 15, 2022 at 9:32pm  

From what I can see, you are trying to re-login from the redirect.

The long answer (with some explanation) is
The rcOauthCallbackEx.html route will be called by the ringcentral auth server (assuming you have set up the route properly in the ringcentral developer app and you are running your app as a server)
You do not need to re-login from the rcOauthCallbackEx.html page. All you need to do is to call the RingCentral.SDK.handleLoginRedirect() function which will get the verification code and pass it to the main window which initiated login

The short answer is

var rcsdk = new RingCentral.SDK({
  server: "",
  clientId: "YOUR_CLIENT_ID_HERE",

var loginOptions = rcsdk.parseLoginRedirect(window.location.hash ||;
  .then(function(ret) {
    console.log("RC Login() return:");
  }).catch(function(e) {
     alert("Login error " + e.message);



in your rcOauthCallbackEx.html file and try things out once


A new Community is coming to RingCentral!

Posts are currently read-only as we transition into our new platform.

We thank you for your patience
during this downtime.

Try Workflow Builder

Did you know you can easily automate tasks like responding to SMS, team messages, and more? Plus it's included with RingCentral Video and RingEX plans!

Try RingCentral Workflow Builder

Developer Platform
Integrated Apps
App Gallery
Developer support
Games and rewards

Resource center
Product Releases
App Download
RingCentral App login
Admin Portal Login
Contact Sales
© 1999-2024 RingCentral, Inc. All rights reserved. Legal Privacy Notice Site Map Contact Us