KeyError 'access_token' when fetching profile info...
# support-questions-legacy
j
Hi Team, We are getting a KeyError 'access_token' on our Flask backend when fetching profile info via Google: supertokens_python/recipe/thirdparty/providers/google.py in get_profile_info at line 58 We think it is likely that the signup API is being called twice and returning a 500 response from Google the second time, which means that the auth_code_response does not have the 'access_token' key, and instead returns the following error: { error: 'invalid_grant', error_description: 'Bad Request' } We have looked at this thread https://discord.com/channels/603466164219281420/1113510798736752692 and its related GH issue (https://github.com/supertokens/supertokens-auth-react/issues/707) but haven't been able to come up with a solution. We also cannot reliably reproduce this error. Could we get some support / should the API be catching this to avoid the KeyError? Thank you in advance!
r
How have you setup the pre built UI? For example, are you embedding it in your custom page? Or have you setup as per our docs? Are you using pages or app dir?
which versions of the frontend and backend SDK?
j
hi @rp_st thank you for your help. We are using the SignInAndUp supertokens component and embedding it in custom modal: import { SignInAndUp } from 'supertokens-auth-react/recipe/thirdpartypasswordless'; import Modal from 'react-bootstrap/Modal'; import UserOnboarding from 'js/apps/default/pages/user/UserOnboarding'; export default function AuthModal({ onHide, show = false, onboarding = false }) { return ( <Modal show={show} onHide={onHide} centered contentClassName='shadow-lg rounded-4' data-testid='auth-modal' backdrop={onboarding ? 'static' : true} > {(!onboarding) ? ( ) : ( )} ); } The frontend SDK version is 0.31.2 (auth-react) and 0.5.0 (web-js). The backend SDK version is 0.12.8.
r
right. So you might want to check if your component (AuthModal) is being remounted or not.
j
thanks will check and get back to you
r
Actually. The signinup component is not related to the callback screen anyway
But I suspect that something is causing our pre built ui to remount. Not sure.
c
What is the pre built ui if not the SignInAndUp component?
r
there is also the callback screen
which is on /auth/callback/google
which uses another component of ours to consume the code
c
How can we prevent that from remounting as we don't include it directly?
r
it should not remount by default. So im not sure why it would be
are you seeing 2 calls to the signinup POST API in your network tab?
If not, then the issue is something else.
c
In some cases it has looked like 2 calls were made from the same IP in close succession, but this is not always the case.
They were far enough apart that it could have been a user refreshing
r
Hmmm
If this issue was there of remounting, it would be two calls really quickly
c
I suspect it might be something else then as we also have examples of a single request being made and it failing with KeyError
r
Right. Ok.
Do you have multiple client ids configured for google?
c
No
Copy code
def setup(app: Flask):
    if settings.TESTING:
        return
    init(
        app_info=InputAppInfo(
            app_name="PROSPECT 100",
            api_domain=settings.auth.API_DOMAIN,
            website_domain=settings.auth.WEBSITE_DOMAIN,
            api_base_path="/api/v1/auth",
            website_base_path="/auth"
        ),
        supertokens_config=SupertokensConfig(
            connection_uri=settings.supertokens.CONNECTION_URI,
            api_key=settings.supertokens.API_KEY,
        ),
        framework='flask',
        recipe_list=[
            session.init(),
            dashboard.init(settings.supertokens.DASHBOARD_KEY),
            thirdpartypasswordless.init(
                flow_type="USER_INPUT_CODE",
                contact_config=thirdpartypasswordless.ContactEmailOnlyConfig(),
                providers=[
                    thirdpartypasswordless.Google(
                        client_id=settings.supertokens.GOOGLE_CLIENT_ID,
                        client_secret=settings.supertokens.GOOGLE_CLIENT_SECRET
                    )
                ],
                email_delivery=EmailDeliveryConfig(override=partial(
                    email_delivery_override, 
                    template=Email.AUTH_PASSWORDLESS_OTP,
                    context_fn=lambda x: {"otp": x.user_input_code}
                )),
            ),
        ]
    )

    Middleware(app)

    # This is required since if this is not there, then OPTIONS requests for
    # the APIs exposed by the supertokens' Middleware will return a 404
    @app.route('/', defaults={'u_path': ''})  
    @app.route('/<path:u_path>')  
    def catch_all(u_path: str):
        abort(404)
r
Hmmm
c
It's affected 82 users in the past 5 days
Not able to reliably reproduce
r
82 out of how many?
c
~5,000
r
do you use server side rendering?
c
No
r
do you have a load balancer / reverse proxy in front of your python app?
c
Yes, we are hosted in Google Cloud Run and the python app is behind nginx
r
when you said there are users who faced this issue, but have just one log for signinup API call, are you certain about this?
cause i can't think of any reason this would be happening other than the APi being called twice, somehow
c
I've double checked and there is exactly a second request. But it was made 23 seconds before
r
hmm.
Do you have any sort of screen recording / analytics of the frontend for any of these users?
c
These came from the same IP
We have a couple screen records but they are not the most insightful
r
maybe the users are doing something weird?
are the users able to login? As in after the first call, are they redirected to the post login screen?
c
r
so something is causing a double navigation to this screen
which means the issue is with the router of the frontend?
how have you added the pre built UI?
c
We are embedding the
<SignInAndUp />
Component within our
<AuthModal />
Component, this is inside of a global context so that we can open and close the auth modal from anywhere in the website. This is the auth modal code:
Copy code
export default function AuthModal({ 
    onHide,
    show = false,
    onboarding = false
}) {
    return (
        <Modal
            show={show}
            onHide={onHide}
            centered
            contentClassName='shadow-lg rounded-4'
            data-testid='auth-modal'
            backdrop={onboarding ? 'static' : true}
        >
            {(!onboarding) ? (
                <SignInAndUp />
            ) : (
                <UserOnboarding />
            )}
        </Modal>
    );
}
and this is the context code:
Copy code
return (
        <AuthContext.Provider value={{ showAuth, hideAuth }}>
            {children}

            <AuthModal show={auth.show} onHide={hideAuth} {...auth.options} />
        </AuthContext.Provider>
    );
which is embedded within our App.js:
Copy code
<UserContext.Provider value={{ user: userContext, setUser: (val) => { setUserContext({ ...val, doesSessionExist: sessionContext.doesSessionExist }) } }}>
                <ConfigContext.Provider value={{ config: configContext, setConfig: (config) => { setConfigContext(config) } }}>
                    <GlobalAuth>
                        <RouterProvider router={router} />
                    </GlobalAuth>
                </ConfigContext.Provider>
            </UserContext.Provider>
We are also adding the supertokens auth routes into a react router dictionary so that you can hit the signinandup page through /Auth. We have a custom route which renders the modal embedded in the page to do this:
Copy code
const router = Sentry.createBrowserRouter([
    ...createRoutes(routes),
    ...SuperTokens.getSuperTokensRoutes()
], {
    future: {
        v7_normalizeFormMethod: true
    }
});
And the route is added as such:
Copy code
export const routes = {
    auth: {
        path: '/auth',
        element: <AuthModal show />
    },
     ....
}
r
hmm.
so the callback screen is rendered by
SuperTokens.getSuperTokensRoutes()
Now there have been complaints in the past that sentry does weird things sometimes (but mostly on the backend)
since you are using
Sentry.createBrowserRouter
- maybe thats doing something that's causing remount for the screens created by
SuperTokens.getSuperTokensRoutes()
(the callback screen is one of them)
or it could be that the enter
router
is getting remounted as well?
c
I'll open a support ticket with Sentry to get their view. I'm not sure what would be causing the
router
to remount, unless it is Sentry? Is there anything we can do in the meantime to handle the request being sent twice in quick succession?
r
depends on how it's happening. When the first request is sent, does it reply before the second one is sent?
based on the screenshot above, it seems that the second post request happens before the first one finishes
@calum7865 one thing you could try for a few days is to remove sentry from the frontend and see if it fixes the issue. You can know fairly quickly if it fixes it or not given that it has happened to 80 users in the last 5 days.. so if it stops happening for 3 days, you know it's likely fixed
c
That's exactly what we've done
r
sounds good
lmk how it goes
c
will do
Thanks for your quick replies - greatly appreciated
r
happy to help 🙂 Im also curious as to why this happens, so we can either fix it, or document it.
b
@rp_st just an update, we have confirmed it was indeed Sentry causing the remount of the component (ironic i know). It seems this is an ongoing issue the sentry team are aware of and they have an open ticket on github to fix this - although they seem quite slow to act upon it: https://github.com/getsentry/sentry-javascript/issues/9228 Cheers again for all of your help!
r
Happy to help 🙂
l
for anyone else who stumbles on this thread in the future also seeing the same behavior with rollbar when configured at the top level
Copy code
<Provider instance={rollbarConfiguredInstance}>
      <ErrorBoundary>{children}</ErrorBoundary>
</Provider>
causing a remount and the double
/auth/signinup
8 Views