Skip to content

Instantly share code, notes, and snippets.

@7iomka
Created June 15, 2023 19:53
Show Gist options
  • Save 7iomka/53fb757e7d2993b5e5dee82e0f25e4df to your computer and use it in GitHub Desktop.
Save 7iomka/53fb757e7d2993b5e5dee82e0f25e4df to your computer and use it in GitHub Desktop.
next.js middleware
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { appConfig } from '@appns/config/app';
import { routes, isAuthRoute, isProtectedRoute, isAdminRoute } from '@/shared/routes';
const redirectTo = (
request: NextRequest,
to: string,
includeFrom = false,
includeReset = false,
) => {
const toUrl = new URL(to, request.url);
if (includeFrom) {
toUrl.searchParams.set('from', request.nextUrl.pathname);
}
if (includeReset) {
toUrl.searchParams.set('reset', 'true');
}
return NextResponse.redirect(toUrl);
};
type ResponsePartial = { isAdming?: true; [key: string]: any };
export function parseJwt(token: string): ResponsePartial | null {
try {
return JSON.parse(atob(token.split('.')[1]));
} catch (e) {
return null;
}
}
export async function middleware(request: NextRequest) {
// Setting cookies on the response
const response = NextResponse.next();
const pth = request.nextUrl.pathname;
const isProtectedPath = isProtectedRoute(pth);
const isAuthPath = isAuthRoute(pth);
const isAdminPath = isAdminRoute(pth);
// skip public routes, except auth routes
if (!isProtectedPath && !isAuthPath) {
return response;
}
// Getting cookies from the request
const token = request.cookies.get(appConfig.authKeys.token);
// If user is authorized - disallow public auth pages
if (!!token && isAuthPath) {
return redirectTo(request, routes.account.main);
}
// If token isn't present, redirect to login
if (!token && isProtectedPath) {
return redirectTo(request, routes.login, true, true);
}
const parsedToken = token ? (parseJwt(token.value) as ResponsePartial) : null;
// Hanlde paths allowed only for admin (isAdmin flag from token)
if (isAdminPath && !parsedToken?.isAdmin) {
return redirectTo(request, token ? routes.account.main : routes.login, !token, !token);
}
return response;
}
export const config = {
matcher: [
/**
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static generated files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
* - static (static files in public folder)
*/
'/((?!api|_next/static|_next/image|favicon.ico|static|shapes).*)',
],
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment