Supabase Magic Link Authentication Issue:

I'm building a Svelte/SvelteKit app with 2 subdomains (pro.domain.com and domain.com) using Supabase auth with magic links. Generating magic link:
const { data } = await supabaseAdmin.auth.admin.generateLink({
type: 'magiclink',
email,
options: {
redirectTo: 'http://localhost:5174/api/auth/callback'
}
});
const { data } = await supabaseAdmin.auth.admin.generateLink({
type: 'magiclink',
email,
options: {
redirectTo: 'http://localhost:5174/api/auth/callback'
}
});
This generates a link like: http://127.0.0.1:54321/auth/v1/verify?token=<token>&type=magiclink&redirect_to=http://localhost:5174/api/auth/callback When clicking the link, Supabase redirects to my callback URL but with no auth data: // My callback endpoint logs: Full URL: http://localhost:5174/api/auth/callback Search params: {} Question: How do I properly handle the Supabase magic link callback to verify the user? What data should I expect from Supabase and how do I access it?
7 Replies
Nareg.T
Nareg.TOP8mo ago
I also would love to hear if there is a better solution to handle both both domains and also works on my local supabase env
Revadike
Revadike8mo ago
first of all, speaking from experience, are you using the same supabase key and url for both the frontend and backend? dont accidentally use the production ones in the frontend and the local ones (from supabase start) in the backend or vice versa that said, I've also has some struggles with the magic link, so I ended up doing it more manually, which worked for me backend
const { data, error } = await supabase.auth.admin.generateLink({
type: 'magiclink',
email
});

const loginToken = data?.properties?.hashed_token;
return loginToken
const { data, error } = await supabase.auth.admin.generateLink({
type: 'magiclink',
email
});

const loginToken = data?.properties?.hashed_token;
return loginToken
frontend
const {
error
} = await supabase.auth.verifyOtp({
token_hash: loginToken,
type: 'email'
});

// if no error, im logged in
const {
error
} = await supabase.auth.verifyOtp({
token_hash: loginToken,
type: 'email'
});

// if no error, im logged in
DevsrealmGuy
DevsrealmGuy8mo ago
The magic link issue is due to email client or in some cases anti-virus extension prefetching the link, meaning by the time a real human will click the link, it has already expired. Revadike solution is similar to what I did, another way is using a proxy page, works too (might cause other issue due to some browser extension prefetching everything), so OTP is the most reliable
Nareg.T
Nareg.TOP8mo ago
@Revadike it seems like it's working, thank you, much appreciated.
Revadike
Revadike8mo ago
nice! I have yet to test in production. Have you?
Nareg.T
Nareg.TOP8mo ago
nah,not yet. but it's working in my local env, for some reason, I thought I had to use the Supabase generated link, but i believe the VerifyOtp() does what it needs to be done.
Revadike
Revadike8mo ago
lmk once u have Well, I just tried it in production. Sadly I'm getting the error "Password should be at least 2048 characters." ok, you can lower it here https://supabase.com/dashboard/project/_/settings/auth but im confused, I thought there was just no password

Did you find this page helpful?