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

Add composable middleware #164

Merged
merged 28 commits into from
Jan 13, 2025
Merged

Add composable middleware #164

merged 28 commits into from
Jan 13, 2025

Conversation

PaulAsjes
Copy link
Collaborator

Fixes #47

Right now we only give users the option to use authkitMiddleware as a drop-in middleware replacement. This works fine if you only want to use middleware for auth purposes, but in more complex apps you might want to stitch together multiple middleware functionalities.

This introduces authkit as a middleware function that allows you to compose middleware yourself at the expense of some of the automatic redirecting and "secure by default" functionality of authkitMiddleware.

Example use:

export default async function middleware(request: NextRequest) {
  // Perform logic before or after AuthKit
  
  // Auth object contains the session, response headers and an auhorization URL in the case that the session isn't valid
  // This method will automatically handle setting the cookie and refreshing the session
  const auth = await authkit(request, {
    debug: true,
  });

  // Control of what to do when there's no session on a protected route is left to the developer
  if (request.url.includes("/account") && !auth.session.user) {
    console.log("No session on protected path");
    return NextResponse.redirect(auth.authorizationUrl);
    
    // Alternatively you could redirect to your own login page, for example if you want to use your own UI instead of hosted AuthKit
    return NextResponse.redirect("/login");
  }

  // Headers need to be included in every non-redirect response to ensure that `withAuth` works as expected
  return NextResponse.next({
    headers: auth.headers,
  });
}

// Match against the pages
export const config = { matcher: ["/", "/account/:path*", "/api/:path*"] };

@PaulAsjes PaulAsjes requested a review from cmatheson January 8, 2025 13:22
@@ -26,7 +26,10 @@ jest.mock('next/headers', () => {
get: jest.fn((name: string) => cookieStore.get(name)),
getAll: jest.fn(() => Array.from(cookieStore.entries())),
set: jest.fn((name: string, value: string | { [key: string]: string | number | boolean }) =>
cookieStore.set(name, value),
cookieStore.set(name, {
Copy link
Collaborator Author

@PaulAsjes PaulAsjes Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Next always stores its cookies in the format

{
  name: string;
  value: string;
  ...other options
}

so changed this to reflect what next actually does.

src/session.ts Outdated Show resolved Hide resolved
@PaulAsjes PaulAsjes merged commit e20e926 into main Jan 13, 2025
0 of 3 checks passed
@PaulAsjes PaulAsjes deleted the pma/composable-middleware branch January 13, 2025 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

How to compose authKitMiddleware with custom middleware?
2 participants