最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

next.js - Secure SPA with dynamic loading using nextdynamic but with *security* - Stack Overflow

programmeradmin0浏览0评论

this works really well to do lazy loading to make a performant SPA:

import dynamic from 'next/dynamic';


const DynamicComponents: Record<string, React.ComponentType<ComponentProps<any>>> = {

  UserPushNotifUpdates: dynamic(() => import('@/components/dd/push-notif/push-notifs-component'), {
    loading: () => <LoadingComponent />,
  }),

  MatchPublic: dynamic(() => import('@/components/dd/match/match-2'), {
    loading: () => <LoadingComponent />,
  }),

  MatchPrivate: dynamic(() => import('@/components/dd/match/match'), {
    loading: () => <LoadingComponent />,
  }),

  AdminHome: dynamic(() => import('@/components/dd/admin/home/admin-home'), {
    loading: () => <LoadingComponent />,
  }),

  AdminDashboard: dynamic(() => import('@/components/dd/admin/dashboard/admin-dashboard'), {
    loading: () => <LoadingComponent />,
  }),

};

the problem is that for security anybody could load any component - I want to restrict access to components in the same way we do with pages.

To my best knowledge, with Next.js, these import calls bypass middleware.

is there a way to get the middleware to work so we can always intercept import calls to modules like this and check for access?

this works really well to do lazy loading to make a performant SPA:

import dynamic from 'next/dynamic';


const DynamicComponents: Record<string, React.ComponentType<ComponentProps<any>>> = {

  UserPushNotifUpdates: dynamic(() => import('@/components/dd/push-notif/push-notifs-component'), {
    loading: () => <LoadingComponent />,
  }),

  MatchPublic: dynamic(() => import('@/components/dd/match/match-2'), {
    loading: () => <LoadingComponent />,
  }),

  MatchPrivate: dynamic(() => import('@/components/dd/match/match'), {
    loading: () => <LoadingComponent />,
  }),

  AdminHome: dynamic(() => import('@/components/dd/admin/home/admin-home'), {
    loading: () => <LoadingComponent />,
  }),

  AdminDashboard: dynamic(() => import('@/components/dd/admin/dashboard/admin-dashboard'), {
    loading: () => <LoadingComponent />,
  }),

};

the problem is that for security anybody could load any component - I want to restrict access to components in the same way we do with pages.

To my best knowledge, with Next.js, these import calls bypass middleware.

is there a way to get the middleware to work so we can always intercept import calls to modules like this and check for access?

Share Improve this question edited Mar 19 at 17:48 Alexander Mills asked Mar 13 at 15:51 Alexander MillsAlexander Mills 101k166 gold badges537 silver badges918 bronze badges 5
  • this actually goes for securing any module being loaded by the client, securely – Alexander Mills Commented Mar 13 at 16:58
  • You can not use built-in middleware when importing components. However, you can build your own middleware. Something like this dynamic(() => { runMiddleware(); return Component }) – Duannx Commented Mar 15 at 6:50
  • that amounts to front end authentication , which nobody really wants, we need to authorize the access only on backend – Alexander Mills Commented Mar 15 at 15:35
  • @Duannx fyi this is probably the right answer: claude.ai/share/10e7e70e-7065-4d35-9862-7cbb77f98966 – Alexander Mills Commented Mar 15 at 20:32
  • never trust the client. Anything that needs authentication/authorization should be verified at the server. Your modules shouldn't need any of that. If they do, you have a security problem. – browsermator Commented Mar 19 at 19:01
Add a comment  | 

1 Answer 1

Reset to default 0

alright so this is pretty straightforward generally, sadly only some will understand it, the key part is to use update (backend) Next.js middleware to match on components/assets being loaded.

this line:

req.nextUrl?.pathname?.startsWith('_next/')

the above will match on the components that get loaded on front-end, and there you can put your backend logic

const privateRouteMatcher = createRouteMatcher([
  '/u/(.*)',
  '/api/p/(.*)',
]);


export default middleware(async (auth, req: NextRequest) => {
 

  const res = NextResponse.next();


  if (req.nextUrl?.pathname?.startsWith('_next/')) {

    // HANDLE ACCESS CONTROL LOGIC HERE
    res.headers.set('x-middleware-cache', 'no-cache');

    return res;
  }

  // For non-private routes, return early with CORS headers
  if (!privateRouteMatcher(req)) {
    return res;
  }

  
   // route to rest of the app
  return res;
});

export const config = {
  matcher: [
    '/(.*)',
  ],
};
发布评论

评论列表(0)

  1. 暂无评论