I'm glad to hear you're enjoying Kinde!
When it comes to handling multitenancy in middleware and protecting routes, here are some best practices and steps you can follow:
Use the withAuth Middleware for Route Protection: The withAuth helper function provided by Kinde is designed to protect routes. If a user is not authenticated, they are redirected to the login page. Once authenticated, they will be redirected back to the protected page they initially requested access to.
Example:
import {withAuth} from "@kinde-oss/kinde-auth-nextjs/middleware";
export default function middleware(req) {
return withAuth(req, {
isReturnToCurrentPage: true
});
}
export const config = {
matcher: ["/admin"]
};
Custom Authorization with isAuthorized Function: For more granular control, especially in a multitenant setup, you can define a custom isAuthorized function. This function can check if the authenticated user has the necessary permissions within a specific organization to access the route.
Example: import {withAuth} from "@Kinde-oss/kinde-auth-nextjs/middleware";
export default withAuth(
async function middleware(req) {
console.log("look at me", req.kindeAuth);
},
{
isAuthorized: ({token}) => {
// Example: The user is authorized if they have the 'edit:projects' permission
return token.permissions.includes("edit:projects");
}
}
);
export const config = {
matcher: ["/admin"]
};
Leverage Organizations for User Management: Utilize Kinde's support for organizations to manage users and their access within your application. You can control who can access specific parts of your application and set roles and permissions for each user in an organization.
Fetching Organization and Permission Data: Use Kinde's SDK to fetch organization and permission data for the authenticated user. This can help you implement logic in your application to show or hide certain features based on the user's permissions within an organization.
Example:
const {getUserOrganizations, getPermission} = useKindeAuth();
console.log(getUserOrganizations());
// Check if the user has permission to create todos
const permission = getPermission("create:todos");
if (permission.isGranted) {
// Show the feature
}
Remember, when implementing multitenancy, it's crucial to ensure that your application's logic correctly segregates data and access based on the organization context. This includes not only protecting routes but also filtering data and actions based on the user's organization memberships and permissions.
For more detailed information and examples, you can refer to the Kinde documentation on multi-tenancy using organizations, NextJS SDK, and NextJS Pages Router SDK v2.