Closed quick007 closed 1 year ago
The oAuth provider redirects you back to http://localhost:3000/settings
.
The url contains a hash with the required data (http://localhost:3000/settings#token=the-actual-token
) to create a client session but the server is not able to read the url hash.
It is therefore necessary to redirect to a page that does not require authentication.
You could create another route /callback
that does not require authentication (the user is not redirect to the login page).
Set redirectTo
to that route and add a query param to the desired page like ?to=/settings
. If a user lands on /callback
check if there is a session on the client side and then redirect to the correct page using the query param.
This is a known drawback and i think the auth team is doing some work to get auth working without relying on client side scripts.
Thanks for the info. Under "Additional Context," I shared a similar solution. Hopefully the team will be able to get auth working without client side scripts though!
We need to document this. For the time being you can find some helpful resources here https://github.com/supabase/auth-helpers/issues/341#issuecomment-1319502599 and here https://github.com/supabase/auth-helpers/issues/341#issuecomment-1319597309
This is a known drawback and i think the auth team is doing some work to get auth working without relying on client side scripts.
This is something we are looking for as well. Ideally we can create the session in getServerSideProps
and redirect on the server side, instead of loading an unauthenticated page for a second, creating the session in javascript and then redirecting.
This will be fixed when PKCE is implemented, but for now the workaround is redirecting to a non-auth'd page first and then to the auth'd page after.
@silentworks What is PKCE? Also, I have a weird bug where even if the user gets redirected to a non-authed page, they need to refresh once to get redirected. I know this probably isn't where to ask for support, but everyone I've asked can't find a fix. Is this a bug? Heres my code:
useEffect(() => {
setUrl(window.location.origin);
if (user && router.isReady) {
if (typeof redirectedFrom == "string")
router.push(decodeURI(redirectedFrom));
else router.push("/");
}
}, [user, router, redirectedFrom]);
@quick007 you can have a look at the diagram here to see how you have to do this currently https://github.com/supabase-community/supabase-by-example/tree/main/magic-link and if you click into the nextjs example you can see the code doing this. PKCE will allow for you to get the token on the server rather than having to depend on the client side code.
Great, ty
Hi guys! Had the same problem you were facing here and got to solve it in a hacky way: So, we need to keep in mind that anything we do for checking the auth session server side (middleware or even server router) are not going to take effect because the social auth needs to be ran client side. So what I did was to set the redirectTo of the social auth to the login page and in my login page I added the following code:
export const supabaseClientComponent = createClientComponentClient()
useEffect(() => {
const {
data: { subscription },
} = supabaseClientComponent.auth.onAuthStateChange((event) => {
if (event === "SIGNED_IN") router.replace("/profile")
})
return () => subscription.unsubscribe()
}, [supabaseClientComponent])
What this is doing is to check for client side auth state changes in the login page, so after I've signed in it will catch the session client side and redirect me to the profile page. This is a nice hack I saw somewhere else. Hope it helps!
@quick007 Hey, i have exact same problem. It redirect user but URL is same and u have to refresh page manually. Did you solve it somehow?
@dvenomb98 as silent mentioned above, you can do it server side: https://github.com/supabase-community/supabase-by-example/tree/main/magic-link
I'm lazy and don't want to rewrite my auth flow.
The way I "fixed" it (seems to work every time) is this:
useEffect(() => {
setUrl(window.location.origin);
if (user && router.isReady) {
if (typeof redirectedFrom == "string")
router.push(decodeURI(redirectedFrom));
else router.push("/");
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [user, router]);
This is probably hackier than the solution mentioned above (although for the one above, you should probably use router.push instead of replace).
Bug report
Describe the bug
If you have middleware auth set up (for example, I want all unauthenticated users to go to the login page), when users log in they'll still be taken to the login page despite a
redirectTo
option set. I'm assuming it can't grab their session for some reason.To Reproduce
Steps to reproduce the behavior, please provide code snippets or a repository:
Create a middleware auth file that redirects to the login page for unauthenticated users:
export const config = { matcher: "/((?!api|_next/static|favicon.ico|login|svg|brand-logos).*)", };
/login
, after logging in, note that it goes back to/login
rather than/settings
Expected behavior
A clear and concise description of what you expected to happen.
I expected it to redirect to
/settings
Screenshots
If applicable, add screenshots to help explain your problem.
none
System information
Additional context
You can temporarily solve this problem by doing something like this: