auth0/nextjs withMiddlewareAuthRequired 导致 API 端点出现 CORS 问题

问题描述 投票:0回答:1

我正在使用 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 使用上下文对象,所以我不知道如何弥合差距。

next.js cors auth0 hono
1个回答
0
投票

正如您所知,中间件正在拦截 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).*)'],
};
© www.soinside.com 2019 - 2024. All rights reserved.