Supabase Email and Password (SSR)
Setting up Supabase for Server Side Rendered authentication.
To make sure Supaboost is working with the latest Supabase/ssr package, we need to make some adjustments. On top of that, it is good to look at some of the functionality of Supabase, to make sure you can access your auth both from localhost and production!
Setting up the Redirect URL
In your project, go to Authentication > URL Configuration
On this page, you can configure where you want to redirect your users for reset password, magic link, invitations and more.
It is important that you update this code:
- For local development, set your Redirect URL to:
http://localhost:3000
- For server hosted, set your Redirect URL to the proper url for your app. In my case:
https://demo-v1.supaboost.dev
You can find more information about Redirect URL configuration here: Supabase URL logic
Make sure to update your URL to your production/server URL once you are ready to go into production. It would be a shame if you don't convert users because they can't log in.
Setting up the Email Provider
In your Supabase project, go to Authentication > Providers > Email
In this part of the application, you can set up what you value:
The options are as follows:
- Enable email provider: Define if you want to use Email/Password for log in
- Confirm email: Define if you want the user to confirm their email (especially good to prevent fake emails)
- Secure email change: Enable for both emails to confirm, disable only for the new email to accept
- Secure password change: Enable for secure (user needs to have logged in), disable for any time updates
On top of the email provider, we can also send out emails to users, for email confirmation, reset password and more.
Setting up Supabase SSR logic
In our (Auth) folder of the Supaboost app, there is a route.ts file. This file is required for supabase/ssr and is new.
Let's have a look at the file to better understand it's logic.
With the route, you can define where users are redirect to for both failed and confirmed has tokens. This way you can make sure users will be able to navigate to the correct folder.
On top of that, the route is reading the information:
- token_hash: verify if there is a token
- type: type of request
- next: url to navigate to
If there is a type and token, a Supabase client is created, which can get, set and remove cookies. If there is a token and type, it will then try to exchange the token for a session, so that the correct user can update the details.
If all is well, user is redirected to "/", else to "/auth/auth-code-error" if there is an error.
With this setup done, we need to also make sure that users are redirected to the confirm/route in the application.
Setting up the email templates
In the guide provided by Supabase, we can directly copy each and every email template. However I wanted to add some nuances to the Email templates for you to better understand how it works.
Before, Supabase used the .ConfirmationURL, which moves users to Supabase then redirects them using the Redirect URL. In the new situation, we have more control over where we redirect users. As such, we can also add additional routes to navigate users to different success pages. More on that later.
<h2>Confirm your signup</h2>
<p>Follow this link to confirm your user:</p>
<p>
<a href="{{ .ConfirmationURL }}">
Confirm your mail
</a>
</p>
In the new template, we see that we have the .SiteURL and .TokenHash. The URL you will understand, the token is a string generated by Supabase specifically for the email redirect.
This token, as we saw in the route, will be exchanged for a Session.
<h2>Confirm your signup</h2>
<p>
<a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}&type=email"
>Confirm your email for SSR</a
>
</p>
An example of the Url that will be generated: https://my-app.com/auth/confirm?token_hash=pkce_7628ee2190e07a7a734f5ce47dbe01f59d5ebfbeb957e9be3b52c6f5&type=email
That means that if you want to change the route, you need to change the path after my-app.com/ and before the ?token_hash.
If you want to divide the users to different pages, for let's say onboarding, what you can do is create an additional route in your Auth folder just like confirm. In the above iamge, we saw that users are redirected to "/". You can say I want to move email confirmation users to the route confirmation, where i use "/onboarding", and all other users through with another route (authentication) "/".
In that example, you would have to change app/auth/confirmation url to "/onboarding" and keep app/auth/onboarding as is.
While also changing the href in the Email template:
// confirm
/auth/confirm?token_hash=
// authentication
/auth/authentication?token_hash=
Setting up the email templates
To make sure you use the correct templates, copy and paste the following templates to the correct Email template variant.
<h2>Confirm your signup</h2>
<p>Follow this link to confirm your user:</p>
<p>
<a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}
&type=email"
>Confirm your email</a
>
</p>
<h2>Confirm your signup</h2>
<p>Follow this link to confirm your user:</p>
<p>
<a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}
&type=email"
>Confirm your email</a
>
</p>
<h2>You have been invited</h2>
<p>
You have been invited to create a user on {{ .SiteURL }}.
Follow this link to accept the invite:
</p>
<p><a href="{{ .ConfirmationURL }}">Accept the invite</a></p>
<h2>Magic Link</h2>
<p>Follow this link to login:</p>
<p><a href="{{ .ConfirmationURL }}">Log In</a></p>
<h2>Confirm Change of Email</h2>
<p>
Follow this link to confirm the update of your email from {{ .Email }} to {{ .NewEmail }}:
</p>
<p>
<a href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}
&type=email_change">
Change Email
</a>
</p>
⚠️ Make sure you change the Reset Password, to be in line with below. The logic for Reset password is on the page "/reset", which means you need to redirect users there.
<h2>Reset Password</h2>
<p>Follow this link to reset the password for your user:</p>
<p>
<a
href="{{ .SiteURL }}/auth/confirm?token_hash={{ .TokenHash }}
&type=recovery&next=/reset"
>Reset Password</a
>
</p>