S
Supabase8mo ago
jace10

Handling Password Reset

Hello, I am trying to figure out if something changed here, as I'm pretty sure this used to work. On my project, I allow users of my application to ask for a password reset if they provide a valid email. This password reset calls this code:
supabase.auth.resetPasswordForEmail(email = email,
redirectUrl = "REDACTED_URL/resetPassword?")
supabase.auth.resetPasswordForEmail(email = email,
redirectUrl = "REDACTED_URL/resetPassword?")
My reset password email config looks like:
<h2>Reset Password</h2>

<p>Follow this link to reset your password:</p>
<p><a href="{{ .SiteURL }}/resetPassword?confirmation_url={{ .ConfirmationURL }}">Reset Password</a></p>
<h2>Reset Password</h2>

<p>Follow this link to reset your password:</p>
<p><a href="{{ .SiteURL }}/resetPassword?confirmation_url={{ .ConfirmationURL }}">Reset Password</a></p>
This correctly results in the user being sent an email with the link to reset password taking them to my webpage. On that webpage, I have a button, and if they click the button, it navigates to the confirmation url, which looks like this:
https://redacted.supabase.co/auth/v1/verify?token=redacted&type=recovery&redirect_to=http://redacted.com/resetPassword?
https://redacted.supabase.co/auth/v1/verify?token=redacted&type=recovery&redirect_to=http://redacted.com/resetPassword?
If I click on the button (or navigate to it directly), it seems to correctly redirect to my provided redirect, with the following in the url:
https://www.redacted.com/resetPassword#access_token=TOKEN&expires_at=1736997049&expires_in=3600&refresh_token=REFRESH&token_type=bearer&type=recovery
https://www.redacted.com/resetPassword#access_token=TOKEN&expires_at=1736997049&expires_in=3600&refresh_token=REFRESH&token_type=bearer&type=recovery
Two things that puzzle me. 1) When I check for a session with
const {data, error} = await supabase.auth.getSession()
const {data, error} = await supabase.auth.getSession()
Session is still null, with no error. I thought when I first implemented this that the session was populated, is that not what visiting the provided confirmation URL is meant to do? 2) I am not sure why the ? I include in my URL is getting wiped out, which then makes it harder to try and access the access token to authenticate the user manually after the fact Any insight appreciated, or please let me know if I am misunderstanding how this flow is supposed to work. Thanks!
4 Replies
tomaspozo
tomaspozo8mo ago
What framework/sdk are you using? I think you are missing a step after navigating to
https://www.redacted.com/resetPassword#access_token=TOKEN&expires_at=1736997049&expires_in=3600&refresh_token=REFRESH&token_type=bearer&type=recovery
https://www.redacted.com/resetPassword#access_token=TOKEN&expires_at=1736997049&expires_in=3600&refresh_token=REFRESH&token_type=bearer&type=recovery
you need to exchange the token for a session, the exact method would depend on the sdk you use
jace10
jace10OP8mo ago
This would be the javascript API. I am using NextJS/React. I thought I would need to exchange the token for a session, but since the question mark isn't included in the redirected url the normal useSearchParams isn't working to get the token out of the url, and I'm trying to find a way to get the param out of the URL without the ? to little success so far
j4
j48mo ago
Looks like the Supabase client you're using to do the reset is using implicit flow. This is because the url after clicking the button has #access_token.... For this to work, you need a Supabase client running on your /resetPassword page that is also using the implicit flow. If you want to do the exchangeCodeForSession method, that requires the pkce flow and changing your email template. Checkout the docs.
jace10
jace10OP8mo ago
Ah ok thank you for the heads up

Did you find this page helpful?