Supabase authentication not working
Hi,
I have setup a refine (headless) + supabase project. I have enabled "Github" as an auth provider and have been following this page:
https://refine.dev/docs/packages/documentation/data-providers/supabase/#this-premade-and-ready-to-use-login-screen-consist-loginpage-and-authprovider-concepts-behind-the-scenes
I can login successfully (either with github or email/password) but a protected page still redirects me to "/login" route when I try to check for authentication on server side i.e. using
getServerSideProps
but it does let me in when using Authenticated
component (see screenshot).
How to make it work with getServerSideProps
?
Thanks,Supabase | refine
Introduction
16 Replies
Hi @kunalvirk. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To achieve authentication control on the server-side with Next.js, you can use your
authProvider
's check
function inside server side functions (getServerSideProps
) to redirect unauthenticated users to other pages like login.
First, you need to install the nookies
package in your project. This package will be used to set/destroy cookies in the login
, logout
and check
functions of your AuthProvider
.
You can install it using the following command:
Then, in your authProvider.ts
file, you should implement the check
function to check for authentication. This function will be used inside getServerSideProps
to redirect unauthenticated users.
Unfortunately, the extracts provided do not contain specific code examples for implementing the check
function in authProvider.ts
or using it inside getServerSideProps
. For more detailed instructions and code examples, you can refer to the refine documentation on Next.js Authentication (https://refine.dev/docs/packages/documentation/routers/nextjs).
Please note that for page level authentication, the server-side approach is recommended.
----------------------
Note: you can ask me a follow up question by @ mentioning me again
:speech_balloon:
----------------------<@798450536004452392> kapa.ai is still learning and improving, please let us how it did by reacting below
optimistic-goldOP•2y ago
@kapa.ai
In the check method in authProvider:
const { data, error } = await supabaseClient.auth.getSession();
this returns null on the server
Let me check the knowledge base for you. One moment! :books:
----------------------
The
getSession
method from Supabase client is a client-side method and it won't work on the server-side because it relies on the window
object to get the session from local storage, which is not available on the server-side.
For server-side, you need to use cookies or similar methods to store and retrieve the session. You can use the nookies
package to handle cookies on both server and client side in Next.js.
Here's a general idea of how you can modify your check
method to work on the server-side:
In the login
method, you would set the cookie after successful login:
And in the logout
method, you would destroy the cookie:
Please replace 'your-cookie-name'
with the actual name you want to use for your cookie.
Remember to pass the context (ctx
) from getServerSideProps
to the check
, login
, and logout
methods.
Please note that the code above is a general guide and might need adjustments based on your specific use case. For more detailed instructions and code examples, you can refer to the refine documentation on Next.js Authentication (https://refine.dev/docs/packages/documentation/routers/nextjs).
----------------------
Note: you can ask me a follow up question by @ mentioning me again
:speech_balloon:
----------------------<@798450536004452392> kapa.ai is still learning and improving, please let us how it did by reacting below
optimistic-goldOP•2y ago
@kapa.ai
Supabase
signInWithOAuth
method does not return an access_token rather it sets two cookies named sb-access-token
& sb-refresh-token
. When checking the cookies using parseCookies method from nookies it return {} object
Let me check the knowledge base for you. One moment! :books:
----------------------
The
parseCookies
method from nookies
is used to parse the cookies from the request headers in the server-side context (ctx
). If it's returning an empty object, it means that there are no cookies in the request headers.
The signInWithOAuth
method from Supabase sets the sb-access-token
and sb-refresh-token
cookies on the client-side. These cookies are httpOnly
, which means they can't be accessed through JavaScript on the client-side for security reasons. They are automatically sent with every request to the server from the client's browser.
If you're not seeing these cookies in your server-side context, it could be due to a few reasons:
1. The cookies are not being sent with the request. This could be because the request is not being made from the same domain that the cookies are set on. Cookies are only sent with requests that are made to the same domain. Make sure your server-side code is running on the same domain that your client-side code is running on.
2. The cookies are being blocked by the browser. Some browsers block third-party cookies by default. Make sure your browser settings allow third-party cookies.
3. The cookies are not being set correctly. Make sure the signInWithOAuth
method is being called correctly and is successfully setting the cookies.
If you're still having trouble, you might want to consider using a different method for server-side authentication. One common method is to use a JWT (JSON Web Token) that is stored in a secure httpOnly cookie. The JWT can be set by your server after successful authentication and then sent with every request to the server.
Unfortunately, the provided extracts do not contain specific code examples or instructions for implementing this method with Supabase and refine. For more detailed instructions and code examples, you can refer to the Supabase documentation on server-side rendering (https://supabase.io/docs/guides/with-nextjs).
----------------------
Note: you can ask me a follow up question by @ mentioning me again
:speech_balloon:
----------------------<@798450536004452392> kapa.ai is still learning and improving, please let us how it did by reacting below
optimistic-goldOP•2y ago
@kapa.ai I confirm that the requests are being made from the same domain. Third party cookies also allowed. I can see the cookies being set as soon as the user is logged in successfuly
Let me check the knowledge base for you. One moment! :books:
----------------------
If you have confirmed that the cookies are being set correctly and the requests are being made from the same domain, then the cookies should be included in the request headers and should be accessible in the server-side context (
ctx
).
However, if you're still not seeing the cookies using parseCookies(ctx)
, it could be due to the httpOnly
attribute of the cookies. httpOnly
cookies are not accessible through JavaScript and are only sent with HTTP requests. They are not accessible in the server-side context of Next.js because it's running in a Node.js environment, not a browser environment.
To access the httpOnly
cookies in your server-side code, you can use the req.headers.cookie
property in the server-side context (ctx
). This property contains a string with all the cookies that were sent with the request.
Here's an example of how you can access the cookies:
This will give you a string with all the cookies. You can then parse this string to get the individual cookies:
Now parsedCookies
should be an object with all the cookies that were sent with the request, including the httpOnly
cookies.
Please note that this method requires the cookie
package. You can install it using the following command:
If you're still having trouble, it might be a good idea to check the ctx.req.headers
property to see if the cookies are being included in the request headers. If they're not there, then there might be an issue with how the requests are being made or how the cookies are being set.
For more detailed instructions and code examples, you can refer to the Next.js documentation on getServerSideProps (https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering) and the cookie package documentation (https://www.npmjs.com/package/cookie).
----------------------
Note: you can ask me a follow up question by @ mentioning me again
:speech_balloon:
----------------------<@798450536004452392> kapa.ai is still learning and improving, please let us how it did by reacting below
optimistic-goldOP•2y ago
@kapa.ai Isn't it a bit strange that after succesful login using the supabase client. The auth provider works fine for client side but does not on server side ? As sson as the user is logged in, I can see that it fills the local storage with credentials (token) but the cookies are behaving weirdly.
Let me check the knowledge base for you. One moment! :books:
----------------------
Yes, it can seem a bit strange, but it's important to understand the differences between client-side and server-side environments.
The Supabase client is designed to work in a browser environment, where it has access to the
window
object and can use it to store session data in local storage. This is why it works fine on the client-side.
On the server-side, however, there is no window
object, and the Supabase client doesn't have access to local storage. This is why it can't retrieve the session data on the server-side.
As for the cookies, they are httpOnly
, which means they can't be accessed through JavaScript. They are only sent with HTTP requests to the server. This is a security feature to prevent sensitive data from being exposed to client-side scripts.
If you're seeing the cookies being set in the browser but not being sent with the requests to the server, it could be due to a few reasons:
1. The cookies are not being sent with the request. This could be because the request is not being made from the same domain that the cookies are set on. Cookies are only sent with requests that are made to the same domain. Make sure your server-side code is running on the same domain that your client-side code is running on.
2. The cookies are being blocked by the browser. Some browsers block third-party cookies by default. Make sure your browser settings allow third-party cookies.
3. The cookies are not being set correctly. Make sure the signInWithOAuth
method is being called correctly and is successfully setting the cookies.
If you're still having trouble, you might want to consider using a different method for server-side authentication. One common method is to use a JWT (JSON Web Token) that is stored in a secure httpOnly cookie. The JWT can be set by your server after successful authentication and then sent with every request to the server.
Unfortunately, the provided extracts do not contain specific code examples or instructions for implementing this method with Supabase and refine. For more detailed instructions and code examples, you can refer to the Supabase documentation on server-side rendering (https://supabase.io/docs/guides/with-nextjs).
----------------------
Note: you can ask me a follow up question by @ mentioning me again
:speech_balloon:
----------------------<@798450536004452392> kapa.ai is still learning and improving, please let us how it did by reacting below
optimistic-goldOP•2y ago
@kapa.ai I am following some supabase documentation, I have setup a route in 'pages/auth/callback' but it also redirects me to login. How to disable authentication on this route?
Let me check the knowledge base for you. One moment! :books:
@kunalvirk That's a great question, but unfortunately I am only capable of responding to a maximum of three questions per thread. Don't hesitate to create a new thread for any further questions you have though. I'm here to help!