Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clerk or any other auth provider support - middleware support #1325

Open
brrock opened this issue Mar 26, 2025 · 8 comments
Open

Clerk or any other auth provider support - middleware support #1325

brrock opened this issue Mar 26, 2025 · 8 comments

Comments

@brrock
Copy link

brrock commented Mar 26, 2025

Is this a question to ask clerk or here. I just would like to create full stack apps with waku

I think waku needs middleware support than I can send clerk a PR that adds a waku package that is basically the next version but a few tweaks and disable app router (and have to ability to add back if waku gets support for it )

Thanks for such a brilliant project

@brrock brrock changed the title Clerk or any other auth provider suppourt Clerk or any other auth provider support - middleware support Mar 26, 2025
@dai-shi
Copy link
Member

dai-shi commented Mar 26, 2025

auth is still a space to explore. #576 is an old issue.
It's not my expertise, and I look for various opinions and suggestions before deciding one.

@brrock
Copy link
Author

brrock commented Mar 27, 2025

I might try and implement a middleware.ts

@brrock
Copy link
Author

brrock commented Mar 27, 2025

If there is an official lib for clerk it will be on their website which is highly popular (people will be like what's this and check waku out)so after I try and add middleware I will send clerk a Pr

@dai-shi
Copy link
Member

dai-shi commented Mar 27, 2025

I'm not sure if you checked this, but just in case:

import('./src/middleware/cookie.js'),
is an example.

Be warned that we plan to merge #1281 soon. So, you'd better wait for it before sending a pr.

@brrock
Copy link
Author

brrock commented Mar 27, 2025

Thanks, what does this allow the user to do. Is it similar to like a nextresponse kind of thing?

@dai-shi
Copy link
Member

dai-shi commented Mar 27, 2025

Probably. Check out the Middleware type. It returns a Handler.

export type Handler = (
ctx: HandlerContext,
next: () => Promise<void>,
) => Promise<void>;

@rmarscher
Copy link
Collaborator

rmarscher commented Mar 28, 2025

React Router v7 is probably a better example to use than NextJS.

https://clerk.com/docs/references/react-router/read-session-data#server-side
https://github.com/clerk/javascript/tree/main/packages/react-router

Waku doesn't have built-in loader functions like React Router. We can just call a function to create the clerk client from a server component or from middleware.

It's possible to implement auth in server components and server functions without Waku middleware by using the Hono context.

Roughly like this -

import { getHonoContext } from 'waku/unstable_hono';
import { getAuth } from '@clerk/react-router/ssr.server';
import { createClerkClient } from '@clerk/react-router/api.server';
import { unstable_redirect as redirect } from 'waku/router/server';

async function performAuth({ c }) {
  const request = c.req.raw; // https://hono.dev/docs/api/request#raw
  const { userId } = await getAuth({ request })

  // Protect the route by checking if the user is signed in
  if (!userId) {
    return redirect('/sign-in?redirect_url=' + request.url)
  }

  // Instantiate the Backend SDK and get the user's full `Backend User` object
  const user = await createClerkClient({ secretKey: process.env.CLERK_SECRET_KEY }).users.getUser(
    userId,
  )

  return {
    user: JSON.stringify(user),
  }
}

function authLoader() {
  const c = getHonoContext();
  const existingPromise = c.get('authPromise');

  if (existingPromise) {
    return existingPromise;
  }

  const authPromise = performAuth({ c });
  c.set('authPromise', authPromise);
  return authPromise;
}

And then call authLoader() from your server components or server functions and control where you await the promise.

React does concurrent rendering of pages and layouts when you are using Suspense so that's why I set the promise into the context so authLoader() can be called multiple times.

@brrock
Copy link
Author

brrock commented Mar 28, 2025

That's great thanks I will try a full implementation later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants