Middleware auth
Answered
MarkMiklos posted this in #help-forum
I am totally new in this middleware part, so basically my app is multi language using next-intl.
mydomain.hu/hu/admin and everything beyond that should be a protected route.
I managed to match /admin and whenever my session is not available it does redirect to mydomain.hu, but for the other pages such as /admin/profile it doesn't.
Is my middleware even correct, or I'm completely on a wrong path here?
Here's my code:
middleware.ts
My auth.ts is just a basic login that sets a token in cookies and the getSession that is called in middleware is checking the cookies for a token and returns a boolean
Any good and bad criticism accepted about my workaround
mydomain.hu/hu/admin and everything beyond that should be a protected route.
I managed to match /admin and whenever my session is not available it does redirect to mydomain.hu, but for the other pages such as /admin/profile it doesn't.
Is my middleware even correct, or I'm completely on a wrong path here?
Here's my code:
middleware.ts
import createIntlMiddleware from 'next-intl/middleware';
import { locales } from "@/navigation";
import {NextRequest, NextResponse} from "next/server";
import {getSession} from "@/auth";
const intlMiddleware = createIntlMiddleware({
locales,
defaultLocale: 'hu',
});
const protectedRoutes = ['/admin']
export default async function middleware(req: NextRequest) {
const session = await getSession();
const protectedPathnameRegex = RegExp(
`^(/(${locales.join('|')}))?(${protectedRoutes
.flatMap((p) => (p === '/' ? ['', '/'] : p))
.join('|')})/?$`,
'i'
);
console.log(protectedPathnameRegex)
const isProtectedPage = protectedPathnameRegex.test(req.nextUrl.pathname);
if (!session && isProtectedPage) {
const absoluteURL = new URL("/", req.nextUrl.origin);
return NextResponse.redirect(absoluteURL.toString());
} else {
return intlMiddleware(req);
}
}
export const config = {
// Match only internationalized pathnames
matcher: ['/', '/admin', '/client', '/(hu|en)/:path*']
};
My auth.ts is just a basic login that sets a token in cookies and the getSession that is called in middleware is checking the cookies for a token and returns a boolean
Any good and bad criticism accepted about my workaround
Answered by MarkMiklos
I have removed the protectedRoutes array and the protectedPathnameRegex and added a pathname split, and then if that array contains 'admin' then it is a protectedPage.
Not the most beautiful approach, but works, should I do some workaround, or it shuld do the job?
Not the most beautiful approach, but works, should I do some workaround, or it shuld do the job?
import createIntlMiddleware from 'next-intl/middleware';
import { locales } from "@/navigation";
import {NextRequest, NextResponse} from "next/server";
import {getSession} from "@/auth";
const intlMiddleware = createIntlMiddleware({
locales,
defaultLocale: 'hu',
});
export default async function middleware(req: NextRequest) {
const session = await getSession();
const isProtectedPage = req.nextUrl.pathname.split('/').includes('admin')
if (!session && isProtectedPage) {
const absoluteURL = new URL("/", req.nextUrl.origin);
return NextResponse.redirect(absoluteURL.toString());
} else {
return intlMiddleware(req);
}
}
export const config = {
// Match only internationalized pathnames
matcher: ['/', '/admin', '/client', '/(hu|en)/:path*', '/admin/:path*']
};
9 Replies
🆙
it didn't solve the issue, how exactly the matcher works? i have defined a protected route /admin and checking with regexp for locale also, does the matcher checks for the routes here as well ? In my understanding the matcher is because of the internationalization? Correct me out please because I'm confused now 😄
@MarkMiklos it didn't solve the issue, how exactly the matcher works? i have defined a protected route /admin and checking with regexp for locale also, does the matcher checks for the routes here as well ? In my understanding the matcher is because of the internationalization? Correct me out please because I'm confused now 😄
I think you need to change this too
const isProtectedPage = protectedRoutes.some(route => route.startWith(req.nextUrl.pathname);
I have to use the regex also
because this matches my locale, and without the locale it doesn't work, and also this "startWith" isn't a valid function
const protectedPathnameRegex = RegExp(
`^(/(${locales.join('|')}))?(${protectedRoutes
.flatMap((p) => (p === '/' ? ['', '/'] : p))
.join('|')})/?$`,
'i'
);
because this matches my locale, and without the locale it doesn't work, and also this "startWith" isn't a valid function
I have removed the protectedRoutes array and the protectedPathnameRegex and added a pathname split, and then if that array contains 'admin' then it is a protectedPage.
Not the most beautiful approach, but works, should I do some workaround, or it shuld do the job?
Not the most beautiful approach, but works, should I do some workaround, or it shuld do the job?
import createIntlMiddleware from 'next-intl/middleware';
import { locales } from "@/navigation";
import {NextRequest, NextResponse} from "next/server";
import {getSession} from "@/auth";
const intlMiddleware = createIntlMiddleware({
locales,
defaultLocale: 'hu',
});
export default async function middleware(req: NextRequest) {
const session = await getSession();
const isProtectedPage = req.nextUrl.pathname.split('/').includes('admin')
if (!session && isProtectedPage) {
const absoluteURL = new URL("/", req.nextUrl.origin);
return NextResponse.redirect(absoluteURL.toString());
} else {
return intlMiddleware(req);
}
}
export const config = {
// Match only internationalized pathnames
matcher: ['/', '/admin', '/client', '/(hu|en)/:path*', '/admin/:path*']
};
Answer
lovely, thanks for your time.