Hey guys we have implemented supertokens
# support-questions
d
Hey guys, we have implemented supertokens in our app and using COOKIE as Token transfer method. But every time we try to login it's stuck in infinite refresh calls. Can anyone help!?
d
This happened to me today... I'm calling
Session.attemptingRefreshingSession()
from the browser (supertokens-web-js package) which fails to find the access token in the cookie. As far as I can tell, it looks like the cause is the API not being able to find the
sAccessToken
cookie, which isn't part of the request as it is
httpOnly
d
It's happening while we try to login. So at the time there won't be anything cookies. And as result of infinite refresh calls the main signin api which sets the cookies, is not being called at all. Because supertokens check whether any existing tokens are there or not before signin/signup
r
hey @DLighten08 can you show us the following: - The backend debug logs when the refresh API is called. - The backend debug logs when the API that returns
401
is called. - The sign in response headers (Screenshot from chrome's network tab)
Also @daledigital - you shouldn't need to call
Session.attemptingRefreshingSession()
manually. Our network interceptors on the frontend should do auto refreshing - is that not happening?
d
Hey @rp here is the network logs where we are getting the response as 200 and the initiator. also the point is none of the APIs are being called which returns 401. and sign is api it self is not being called due to this infinite. you can check the initiator of the first refresh call )

https://cdn.discordapp.com/attachments/1100422802256969788/1100655294759043153/Screenshot_2023-04-26_at_10.57.00_AM.png

https://cdn.discordapp.com/attachments/1100422802256969788/1100655294985539584/Screenshot_2023-04-26_at_10.57.29_AM.png

https://cdn.discordapp.com/attachments/1100422802256969788/1100655295233019934/Screenshot_2023-04-26_at_10.59.04_AM.png

This is the backend log for the infinite refresh.

https://cdn.discordapp.com/attachments/1100422802256969788/1100655504931434526/Screenshot_2023-04-26_at_11.01.36_AM.png

r
can you enable backend debug log and show the output please?
d
sure give a min
here are the logs from debug. FYI: we are using super-token-web-js version 0.5.0 as FE SDK. https://cdn.discordapp.com/attachments/1100422802256969788/1100659049609039902/message.txt
r
Right. This might be an issye with the backend integration you have done with our SDK. Our SDK correctly says that it should return an
UNAUTHORISED
error, but the golang server is still returning a
200
. Have you followed our guides properly? Seen the golang example apps: https://github.com/supertokens/supertokens-golang/tree/master/examples
d
also with every refresh it's updating the browser-tabs-lock-key-refresh_token_use in localstorage.
r
that's expected.
the issue is mostly on your backend - how you have integrated our middleware probably.
Copy code
r := chi.NewRouter()
    r.Use(cors.Handler(cors.Options{
        AllowedOrigins:   append([]string{ar.cfg.WebsiteDomain}, ar.cfg.CORSDomains...),
        AllowedMethods:   []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
        AllowedHeaders:   append([]string{"Content-Type"}, supertokens.GetAllCORSHeaders()...),
        AllowCredentials: true,
    }))

    r.Use(supertokens.Middleware)

    r.Get("/session-info", session.VerifySession(nil, ar.GetSessionInfo))
But this backend works fine with the demo front end app. Which makes me believe the backend is fine. The refresh issue happens intermittently, some users are still able to log in.
r
are you, @mayankgopronto and @DLighten08 working on the same project? Im confused.
d
Yes
r
right. Refresh sending a 200 when no token is passed to it is definitety a backend issue
what happens if you call the refresh API from postman without any refresh token?
Do you get back a 200 status code or a 401?
m
So figured out the problem. It was a backend issue, in the
supertokens.Init()
I had passed custom
ErrorHandlers
. But I hadn't set
401
in
OnUnauthorised()
override. Thats why it returned
200
as the default. Thanks, fun debugging excercise anyway. 🙂
r
right! cool
d
Feel free to start a new thread for this (I don't know how) as it seems unrelated to this topic from the others. I was following the guide here: https://supertokens.com/docs/thirdparty/common-customizations/sessions/ssr I'm attempting to protect a route on the server-side by checking the session, then redirecting to the client-side route:
/auth/refresh-session
when
TRY_REFRESH_TOKEN
or
UNAUTHORISED
is returned by the server-side
SessionNode.getSession
r
ahh ok. In this case, you do need to call
attemptingRefreshingSession
. But is that not working?
d
Sorry,
SessionWeb.attemptRefreshingSession
works correctly as far as I can see. It successfully finds the refresh token in the cookie then attaches the refreshed session as a cookie in its response. The problem appears to be in the invocation of
SessionNode.getSession
. This always results in
UNAUTHORISED
after executing milliseconds after the client-side refresh.
Upon receiving
UNAUTHORISED
, I redirect back to the client-side refresh route and that creates the loop.
r
can you enabled backend debug logs and show me the output for when
SessionNode.getSession
returns
UNAUTHORISED
(after client refresh)
The first log is when I visit the protected route (called to
SessionNode.getSession
)
r
and then after the
Sending response to client with status code: 200
, there are no more logs from
getSession
?
d
I changed the redirect to prevent the loop - I'll post a one-iteration loop set of logs
r
So whats the api domain and website domain values in appinfo?
d
Copy code
appInfo: {
    appName: "My Site",
    apiDomain: process.env.VERCEL_URL ?? "http://localhost:5173",
    websiteDomain: process.env.VERCEL_URL ?? "http://localhost:5173",
  },
I'm using QwikJS btw. I am using API routes so my middleware is hosted on
http://localhost:5173/auth/[...]
and the client-side session handling is also there:
http://localhost:5173/auth/callback/linkedin
and
http://localhost:5173/auth/refresh-session
r
this appInfo should not work cause both the websiteDomain and the apiDomain are the same & the websiteBasePath and the apiBasePath are the same
so you might wanna add apiBasePath:
/api/auth
or something
d
Hmm, why must the base paths be different?
r
cause otherwise if you hit
http://localhost:5173/auth/...
should our middleware handle it? Or should the webserver route?
anyway, this is a different issue. for the SSR thing, can i see the request header for the request thats made by the browser when you navigate to the protected page?
d

https://cdn.discordapp.com/attachments/1100422802256969788/1100712683986239610/image.png

r
and can i see the refresh API call request and response? A full screenshot
d
I'm not sure what you mean
r
so when the refresh call is made to the backend, it's a network request - so it will shown up on the network tab
so what are the reqeust / response headers from that?
d
Ohh

https://cdn.discordapp.com/attachments/1100422802256969788/1100714076469993512/image.png

r
thats odd. the response header has no sAccessToken cookie being set?
or am i just not being able to see in the screenshot?
d
Yeah, seems that way:

https://cdn.discordapp.com/attachments/1100422802256969788/1100714883315679262/image.png

r
no i mean in the response from the refresh API cll
is there no sAccessToken cookie?
d
Yeah, that screenshot shows the Response Cookies which only has the refresh token
But isn't just using the current access token okay?
r
no.. it should set the access token as well.. are you doing something on the backend via overrides? Or handling sending the response on your own?
which versions of the forntend / backend SDk are you using?
d
Yeah, I'm doing something weird with the middleware handler because QwikJS's
req
and
res
are not compatible with ExpressJS
req
and
res
- I've (horribly) built custom request and response objects to pass to the middleware. Quite possible that the cookie setter has a bug....

https://cdn.discordapp.com/attachments/1100422802256969788/1100716522642608188/image.png

That's my
/auth/[...]
endpoint handler
r
right. So that may be why things arent working
you need to make sure that your custom req / res is able to set cookies properly
d
Okay, so I should expect
sAccessToken
to be set in the refresh response? I'll comb through
supertokens-node
to see what method it's doing to set the cookie
Cheers! (you should charge for this btw!)
r
Yes. Also for the sign in / sign up response etc..
haha yea.. well.. we do have paid support options. But we really care about users getting it to work - helps us improve stuff and find bugs
d
It seems to have set the cookies for that at least (I'm using a custom provider for LinkedIn OAuth) as they are in the request already

https://cdn.discordapp.com/attachments/1100422802256969788/1100717802521890896/image.png

r
right. So i wonder why the refresh API is not setting both the cookies.. weird.
d
Interesting... I added a SuperTokens framework for Qwik instead. It seems as though the access token value containing
=
is problematic when retrieving the value from a cookie. Here's my access token from SuperTokens:
Copy code
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0=.eyJzZXNzaW9uSGFuZGxlIjoiNGIzNjlmZTQtNGQxNC00ODI1LTliYjgtZjM0MWQxMmZlZWM2IiwidXNlcklkIjoiMzYzYzIxNDctMzU5Zi00ODllLWE5YWQtNWY4M2FhMmI1YWZkIiwicmVmcmVzaFRva2VuSGFzaDEiOiJjZTAxZTcwNTFiM2ZiYjgyOTQ3MzM0NmY0N2ViM2MyMWY0MmZiYzkxNDFkMDIxM2M4ZWQ1YWQ1YjZlNTQwZjEzIiwicGFyZW50UmVmcmVzaFRva2VuSGFzaDEiOiI0NDM0OGY3ZjgzMDI2ZjlkNjZjNDMyNjVhMzM1MDJiZWM3MzRiZGRkNzUxMzEwNDdhYjNhNGQyNTVmZmM4NWM2IiwidXNlckRhdGEiOnt9LCJhbnRpQ3NyZlRva2VuIjpudWxsLCJleHBpcnlUaW1lIjoxNjgyNTE0NTkyNDkyLCJ0aW1lQ3JlYXRlZCI6MTY4MjUxMDk5MjQ5MiwibG1ydCI6MTY4MjUxMDk5MjQ5Mn0=.p5z2/F7RjUSVmFWrICLQbl06mL9a6IxEQKrr+14gjdYfRlvg5ODJQxABSvrjZsPv9kxo3mayANffPlzsaMgRMTuSAgTM5NbdXeh0XKWl6WVfA6CAtke9HnHRJPWtK5UnkN2el+puqPGQYECKJJ5M0oeo6zwI4HwtWnMGLFNuWLH8t5CwT/9aKKbOGiROCEB/41YL1+To8FB6zBXmSMn5a4h3Burf2SE9PNjraaxNKSW5LA+x9LiBNKKbaafAGMHTlNos1qNi+tPlf+o//qKGchmZYpnMzx+ny0XQB5iX4Rfp8V7zAlf41jrO+BR92MCX1U98m8qarU10RZeZQQoGwQ==
When fetching the access token from the Qwik City framework, the value is:
Copy code
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsInZlcnNpb24iOiIyIn0
Qwik City is parsing the cookie from the header and splitting the cookie key-values by
=
r
i think you need to url encode the cookie before setting it. That's what other frameworks do by default.
i just logged into my express app and as you can see, the sAccessToken is url encoded

https://cdn.discordapp.com/attachments/1100422802256969788/1100758609647902730/Screenshot_2023-04-26_at_17.51.25.png

d
Nice! Qwik also url encodes the cookie value but in their approach, they drop the rest of cookie value after the
=
: bug in their approach on line 63

https://cdn.discordapp.com/attachments/1100422802256969788/1100759385296355459/image.png

r
right.
d
Hey @rp does supertokens init method does the process in sync or async?
r
sync
d
Okay . Thanks
17 Views