Logo-amall

On next.js I'm using a protected route like in this example: https://github.com/nhost/nhost/blob/main/examples/nextjs/pages/guarded-ssr.tsx However, "nhostSession" is always null. This is strange since on the client-side React, "useAccessToken()" does return a value, which confirms that I'm indeed logged in. How do I get access to the authenticated state and user inside getServerSideProps?

Last active 7 months ago

13 replies

9 views

  • EL

    On next.js I'm using a protected route like in this example:

    https://github.com/nhost/nhost/blob/main/examples/nextjs/pages/guarded-ssr.tsx

    However, "nhostSession" is always null. This is strange since on the client-side React, "useAccessToken()" does return a value, which confirms that I'm indeed logged in.

    How do I get access to the authenticated state and user inside getServerSideProps?

  • OS

    I had the same issue but (for now) went with https://docs.nhost.io/reference/nextjs/create-server-side-client instead. I use this function for every ssr-route and that does not feel optimal. E.g:

    export default withAuth(MyPage);
    
    export async function getServerSideProps(context) {
      const client = await createServerSideClient(
        process.env.NHOST_BACKEND_URL,
        context
      );
    
      const { data, error } = await client.graphql.request(
        gql`
          query GetThings($limit: Int!) {
            things(limit: $limit) {
              id
              name
            }
          }
        `,
        {
          limit: 10,
        }
      );
      if (error) {
        return {
          notFound: true,
        };
      }
      return {
        props: {
          ...data,
        },
      };
    }
    
  • OS

    The route is protected on client-side as I understand it, so in my case the request to server would not go through if the client is not authenthicated

  • OS

    Actually nvm! I see now that I am not authenticated on SSR using this approach. My approach only works because I only fetch public data on SSR.

  • EL

    It it's possible, I would recommend to not do SSR and instead only fetch data client side. It's much easier to maintain and reason about.

    About you not being signed-in in getStaticProps: Do you have a public repo where we can look and test the code?

  • EL

    @elitan Don't have a public repo, but your example I linked has the same code. Not having authenticated state on SSR is very limiting and will make the application slower. I have to wait for the browser to render the page first to THEN request data.. or to THEN redirect to a login page, it's far from ideal.

  • EL

    That's how facebook/twitter/vercel and others are doing it. I think it's a pretty good pattern.

  • EL

    or do you have some special requirements of speed you need to hit? Curious to understand.

  • EL

    I don't think my requirements are special.. if someone requests a resource they don't have access to, the server should be able to deny access to the resource. In fact, if you look at your code sample, that's how you expect it to work too, but it doesn't:

    export const getServerSideProps: GetServerSideProps = async (context) => { const nhostSession = await getNhostSession(BACKEND_URL, context) return { props: { nhostSession } } }

    nhostSession is empty. Ideally, I could grab nhostSession.user.id and do things with it on the server, like

    return { props: { usersOrders } }
    This would allow me to send the data to the client right away which saves the client a trip.

  • EL

    Right. Can you console log the BACKEND_URL variable to make sure it's correct?

  • EL

    It is not empty. Also, I checked context.req.rawHeaders and it has the refreshToken in there. So to me it seems the method "getNhostSession()" doesn't seem to be working at all

  • EL

    looks like the issue may be in createServerSideClient.

    It's using js-cookie to read a cookie called "nhostRefreshToken", however it's returning null.

    I do see the cookie in the header, so perhaps it should be read from the header directly:

    "cookie": "nhostRefreshToken=f80f4b3b-04a0-4225-afa4-adf62f9c012d; nhostRefreshTokenExpiresAt=2022-08-03T19:05:37.850Z",

  • EL

    @oskery @elitan I was able to finally get a user on the SSR side by doing this:

    `
    const myRefreshToken = context.req.cookies["nhostRefreshToken"];

    const {session,error} = await nhost.auth.refreshSession(myRefreshToken);
    

    console.log(session.user);
    `

    There seems to be a bug with how createServerSideClient is reading cookies which is why it keeps returning null.

Last active 7 months ago

13 replies

9 views