supabase-js
supabase-js copied to clipboard
React Native - Expo, Password Reset, redirect URL and Exchange authorization code.
Bug report
- [x] I confirm this is a bug with Supabase, not with my own application.
- [x] I confirm I have searched the Docs, GitHub Discussions, and Discord.
- Related issues (#5663), (https://github.com/supabase/auth-helpers/issues/567)
Describe the bug
I am encountering difficulties with the password reset feature in while developing a React Native Expo application. The password reset is not functioning as expected, and I am experiencing inconsistent behavior with the redirect URL. Additionally, how to handle reset password after redirect what is code
?
Actual Behavior
-
Sometimes it's redirect to base URL
exp://127.0.0.1:8081
and some time it is redirecting to provided URLexp://127.0.0.1:8081/--/resetPassword
, -
Then at final approach as supabase docs:
// The code is retrieved from the query parameter - use whichever mechanism is recommended
// for your app/framework. This is just an example.
const code = url.searchParams.get('code')
// call the Supabase API to exchange the code for a session
await supabase.auth.exchangeCodeForSession(code)
However, the query parameter looks like this:
exp://127.0.0.1:8081/--/resetPassword#access_token=123&expires_in=3600&refresh_token=123&token_type=bearer&type=recovery"
-
Redirect URLs
-
Code snippets:
supabase.ts
import "react-native-url-polyfill/auto";
import * as SecureStore from "expo-secure-store";
import { createClient } from "@supabase/supabase-js";
import { SUPABASE_ANON_KEY } from "@env";
import { SupabaseAuthClientOptions } from "@supabase/supabase-js/dist/module/lib/types";
const ExpoSecureStoreAdapter = {
getItem: (key: string) => {
return SecureStore.getItemAsync(key);
},
setItem: (key: string, value: string) => {
SecureStore.setItemAsync(key, value);
},
removeItem: (key: string) => {
SecureStore.deleteItemAsync(key);
},
};
const supabaseUrl = "https://bbrkeceesipzffkdvfpd.supabase.co";
const supabaseAnonKey = SUPABASE_ANON_KEY;
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
auth: {
storage: ExpoSecureStoreAdapter as SupabaseAuthClientOptions["storage"],
autoRefreshToken: true,
persistSession: true,
detectSessionInUrl: false,
},
});
LoginScreen.ts
const resetPassword = async (email: string) => {
const resetPasswordURL = Linking.createURL("resetPassword");
const { data, error } = await supabase.auth.resetPasswordForEmail(email, {
redirectTo: resetPasswordURL,
});
};
Screenshots
System information
- React Native: 0.72.3
- Expo: ^49.0.0
- Expo Linking: ~5.0.2
- Supabase: ^2.32.0
To take advantage of the exchange code route method, you need to set auth > flowType option to pkce for your supabase client
However, the query parameter looks like this: exp://127.0.0.1:8081/--/resetPassword#access_token=123&expires_in=3600&refresh_token=123&token_type=bearer&type=recovery"
Multiple problems here:
- As @j4w8n mentioned you need flowtype set to pkce.
- For non PKCE flow you need to replace the # with ? to be able to extract it from the query.
Augment this for PKCE flow once you have that enabled. You also need URL polyfill to be installed.
const parsedUrl = url_with_code_as_hashtag.replace("#", "?");
const url = new URL(parsedUrl);
const access_token = url.searchParams.get("access_token");
const refresh_token = url.searchParams.get("refresh_token");
// Handle code exchanges
I'm using Supabase without PKCE with success from the above code.
However, the query parameter looks like this: exp://127.0.0.1:8081/--/resetPassword#access_token=123&expires_in=3600&refresh_token=123&token_type=bearer&type=recovery"
Multiple problems here:
- As @j4w8n mentioned you need flowtype set to pkce.
- For non PKCE flow you need to replace the # with ? to be able to extract it from the query.
Augment this for PKCE flow once you have that enabled. You also need URL polyfill to be installed.
const parsedUrl = url_with_code_as_hashtag.replace("#", "?"); const url = new URL(parsedUrl); const access_token = url.searchParams.get("access_token"); const refresh_token = url.searchParams.get("refresh_token"); // Handle code exchanges
I'm using Supabase without PKCE with success from the above code.
That is by design. The supabase client, in non-pkce mode, should be handling that scenario automatically.
That is by design. The supabase client, in non-pkce mode, should be handling that scenario automatically.
Yes I'm aware. Not Supabase problem I'm mentioning.