middleware icon indicating copy to clipboard operation
middleware copied to clipboard

Example with Supabase AUTH

Open CarlosZiegler opened this issue 2 years ago • 16 comments

Hey! I am playing with HONO and created an example using SUPABASE for AUTH, I will deploy it with docker, this is a "Work in Progress" some feedback are welcome.

Built With: -Node.js -PNPM -TypeScript -Supabase -Drizzle -Zod -Vitest -Biome -Sentry

Link : https://github.com/CarlosZiegler/hono-supabase

CarlosZiegler avatar Jan 13 '24 19:01 CarlosZiegler

Hey @CarlosZiegler that's quite nice! 👍

I think this would be a nice idea for creating an article or a Guide on how to build an app from scratch.

@yusukebe wdyt?

rafaell-lycan avatar Jan 29 '24 12:01 rafaell-lycan

Two improvements I can see:

  • It doesn't use the newer ssr package, which has a different API.
  • On refresh, the code doesn't seem to update the cookie sent back to the client.

I hacked a version based on yours with the above changes. If you want I can make a PR and send your way.

firstian avatar Jun 12 '24 18:06 firstian

@firstian go ahead!!!

CarlosZiegler avatar Jun 12 '24 18:06 CarlosZiegler

I found some bugs with the middleware code provided by Supabase doc. I'll need to debug it enough to be able to proceed. That sample code seems to not work when the cookie is chunked.

firstian avatar Jun 15 '24 18:06 firstian

Hi, I'm trying to connect HONO with Supabase as the backend and Next.js as the frontend. How do I connect them and verify the JWT that comes to the backend with Supabase?

@CarlosZiegler @firstian .

omesh845 avatar Jun 27 '24 04:06 omesh845

You can look at the repo linked in OP to see how it works. The gist is to create the server client with the callbacks to get/set/delete cookies, and then call getUser() to validate the cookie before returning from the middleware.

firstian avatar Jun 28 '24 00:06 firstian

Thanks! I am new to web development, and while this looks very good, the packages used don't seem to be the latest versions, which is a bit overwhelming for me.

I'm unsure about the best approach for handling authentication. Should I:

  1. Authenticate directly from Next.js to Supabase and then verify the token in the Hono backend?
  2. Handle the entire authentication and verification process in the Hono backend?

Which method is more developer-friendly, or is there a commonly used method? How should I go about implementing it?

omesh845 avatar Jul 02 '24 16:07 omesh845

Thanks! I am new to web development, and while this looks very good, the packages used don't seem to be the latest versions, which is a bit overwhelming for me.

I'm unsure about the best approach for handling authentication. Should I:

  1. Authenticate directly from Next.js to Supabase and then verify the token in the Hono backend?
  2. Handle the entire authentication and verification process in the Hono backend?

Which method is more developer-friendly, or is there a commonly used method? How should I go about implementing it?

If you're using Supabase as the auth backend, then you're doing 1. Not sure what you mean by "handle the entire process in Hono backend." Do you mean creating your own JWT in the hono backend? That wouldn't be using Supabase as your auth backend, no?

firstian avatar Jul 02 '24 19:07 firstian

Uhm, ok, so how do setup my authentication (using supabase) safe, please point me right way.

Also could you share code for your new improved version you mentioned in previous post.

omesh845 avatar Jul 02 '24 19:07 omesh845

The docs are here: https://supabase.com/docs/reference/javascript/auth-api

If you're not familiar with auth, it's a bit hard to understand. If you want to use social login, you should look at that part of the doc specifically, because the flow is a little different. I suggest you just get auth working with a normal page first. Only after that you try and wire in Hono.

firstian avatar Jul 02 '24 20:07 firstian

Two improvements I can see:

  • It doesn't use the newer ssr package, which has a different API.

  • On refresh, the code doesn't seem to update the cookie sent back to the client.

I hacked a version based on yours with the above changes. If you want I can make a PR and send your way.

@firstian would you be able to provide this code since I'm struggling with both of these issues right now. Currently sending in an auth token to the middleware but it seems that it doesn't refresh and causes authentication errors

NeilMisra99 avatar Nov 11 '24 07:11 NeilMisra99

I would recommend something like this:

// supabase.ts

import { createServerClient, type CookieOptions } from "@supabase/ssr";
import type { Context } from "hono";
import { getCookie, setCookie } from "hono/cookie";

export function createClient(c: Context) {
  return createServerClient(process.env.SUPABASE_URL!, process.env.SUPABASE_ANON_KEY!, {
    cookies: {
      getAll: () =>
        Object.entries(getCookie(c)).map(([name, value]) => ({ name, value })),

      setAll: (cookies) => {
        cookies.forEach(({ name, value, options }) => {
          setCookie(c, name, value, {
            ...options,
            sameSite:
              options.sameSite === true
                ? "strict"
                : options.sameSite || undefined,
          });
        });
      },
    },
  });
}

This client automatically refreshes tokens for logged-in users.

If you want to run it for all request, you can just do:

app.use(async (c, next) => {
  // Automatically refresh supabase auth tokens for all logged-in users on all requests
  createClient(c);
  await next();
});

To get the user:

app.get("/user", async (c) => {
  const supabase = createClient(c);
  const {
    data: { user },
    error,
  } = await supabase.auth.getUser();
  if (error || !user) {
    return c.json({ error: "Unauthorized" }, 401);
  }

  return c.json({ user });
});

ptts avatar Nov 17 '24 15:11 ptts

@ptts But would this work for a Hono.js backend being deployed on Cloudflare Workers with client side being a Next.js app on Vercel? As far as I remember, cookies only work when dealing with same domains right?

NeilMisra99 avatar Nov 19 '24 06:11 NeilMisra99

@ptts But would this work for a Hono.js backend being deployed on Cloudflare Workers with client side being a Next.js app on Vercel? As far as I remember, cookies only work when dealing with same domains right?

Hey, just curious if you learned more about this Planning to use this exact same stack

marcoaleixo avatar Feb 08 '25 17:02 marcoaleixo

@ptts But would this work for a Hono.js backend being deployed on Cloudflare Workers with client side being a Next.js app on Vercel? As far as I remember, cookies only work when dealing with same domains right?

I don't see why not. There is nothing preventing you from serving both apps from the same domain via different subdomains, e.g. www.domain.com for your Next.js Vercel app and api.domain.com for your Hono Backend on Vercel. This way, all cookies stay in a first party context.

ptts avatar Feb 08 '25 18:02 ptts