我正在使用 Auth0 和 Next.js 构建一个基于多租户子域的应用程序,并以 Hono 作为路由器。我在 middleware.ts 中使用 withMiddlewareAuthRequired 来保护我的应用程序并根据用户的子域重定向用户。我的中间件看起来像这样:
export default withMiddlewareAuthRequired( async function middleware(request: NextRequest) {
const response = NextResponse.next();
const pathname = request.nextUrl.pathname;
const host = request.headers.get('host');
const session = await getSession(request, response);
if (host) {
const domain = getDomain(host, true);
const segments = host.split('.');
//check for subdomain existence
if (host.includes('localhost') ? segments.length > 1 : segments.length > 2) {
//if user access url with subdomain and at root (example: abc.domain.com)
if (pathname === '/') {
//redirect user to abc.domain.com/main
return NextResponse.redirect(
process.env.NODE_ENV === 'production' ? `https://${host}/main` : `http://${host}/main`
);
//redirect to error page if user don't have access to the subdomain
} else if (session && segments[0] !== session.user.org_name) {
return NextResponse.redirect(
process.env.NODE_ENV === 'production'
? `https://${domain}/error/401/unauthorized_org`
: `http://${domain}/error/401/unauthorized_org`
);
}
//if user try to access /main without subdomain (example: domain.com/main)
} else if (pathname === '/main') {
//redirect user to homepage
return NextResponse.redirect(
process.env.NODE_ENV === 'production' ? `https://${host}` : `http://${host}`
);
} else {
return NextResponse.next()
}
}
})
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
};
这对于保护页面和 API 路由非常有效。但是,调用 API 路由会导致错误:
从源“http://abc_company.localhost:3002”获取“http://localhost:3002/api/organizationFromId/org_IA9V4aMfsDJwcCkW”的访问已被 CORS 策略阻止:无“Access-Control-Allow-Origin”标头存在于所请求的资源上。如果不透明响应满足您的需求,请将请求模式设置为“no-cors”以在禁用 CORS 的情况下获取资源。
如果我通过将 api 路由包含在匹配器中来将其从保护中排除,如下所示:
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico|api).*)'],
};
这样就不会出现 CORS 错误,但 API 路由不会受到保护。
我确实在我的路由处理程序中添加了 app.user('*', cors()) (我正在使用 Hono)。
我确实知道 withApiAuthRequired
export default withApiAuthRequired(function Protected(req) {
const session = getSession();
...
});
但它期望 Nodejs req res 其中 Hono 使用上下文对象,所以我不知道如何弥合差距。
正如您所知,中间件正在拦截 API 请求并阻止处理 CORS。
您可以通过执行以下操作来单独保护 Hono 内部的 API 端点:
import { Hono } from 'hono';
import { cors } from 'hono/cors';
import { getSession } from '@auth0/nextjs-auth0';
const app = new Hono();
// Enable CORS
app.use('*', cors());
app.use('/api/*', async (c, next) => {
const req = c.req.raw;
const res = c.res.raw;
try {
const session = await getSession(req, res);
if (!session) {
return c.json({ error: 'Unauthorized' }, 401);
}
c.set('session', session);
await next();
} catch (error) {
return c.json({ error: 'Unauthorized' }, 401);
}
});
app.get('/api/organizationFromId/:orgId', (c) => {
const session = c.get('session');
const orgId = c.req.param('orgId');
return c.json({ orgId, user: session?.user });
});
export default app;
现在您可以从中间件中排除 api 路由并重新启用中间件:
export const config = {
matcher: ['/((?!_next/static|_next/image|favicon.ico|api).*)'],
};