A while back, I tried extending Supabase's OAuth API into this project I'm building, but I struggled with it for a while because I was new to the whole idea of using it in a project — any project at all!
This guide is a very short one. So, I'll jump right to it.
Basic setup
For starters, if you want to enable OAuth in your app with Supabase, you would need to use a snippet similar to the one from their docs.
You need to include the redirectTo
property in theoptions
object to specify where to take your users when the OAuth flow with your selected provider completes.
It is good to always specify this, so you have control of what to do with the information (mostly a token) that you get from the OAuth flow. The problem I had with Supabase's doc is that there isn't any information on how to handle redirect urls or what exactly one would do when the response comes back.
If you don't include a redirect URL, you'll be taken back to your app's index route. In this case, localhost:5173
since I'm using vite for my project. process.env.APP_URL
has the value, hence the reason I used it in the snippet above.
Exchange access token for user data
Since I've specified my redirect url to be localhost:5173/oauth
from the snippet above. I needed to create a new route/page so I can extract the access_token
parameter from the URL.
Here's what my /oauth
route looks like
In the snippet above, I'm doing a couple of things, but the most important one is the exchangeTokenForUser
function. In that function, I read the access_token
parameter from the URL segment.
But, before I could do that. I had to omit the "#"
with this
If the request is successful, I store the access token in a cookie — This isn't necessary since Supabase already handles the user session for us — I just chose to do so. Think of it as a personal preference.
Then I proceed to exchange the token for user data. Supabase's auth.getUser()
method accepts an optional token
argument that you can pass to it. So, here's what the exchange
function looks like
When that's successful, I pass the user data to the authenticator
function from my AuthProvider
to update the user's logged-in state and re-route them to the dashboard with the useNavigate()
hook from React Router, and a toast component from my ToastProvider
is rendered showing the successful message.
When the process isn't successful, they're taken back to the "/signin"
route. To make sure that this works accordingly. I made sure to include the necessary dependencies in the dependency array of the Effect
hook.
Wrapping up.
This took me quite a while to figure out. I remember asking questions in the Supabase Discord community. Heck! I even went on to start a discussion around this in their repo.
I'm glad I was able to figure this out though, so you don't have to go through the stress I went through, trying to figure it out.
Although there may be other approaches to solving this problem, I haven't found any. This came easily to me. But, feel free to use whatever works for you and ping me, perhaps, on Twitter, when you find any.