next auth middleware
Answered
Mike posted this in #help-forum
MikeOP
Hello, how can I extend the middleware so that I can query whether the user has the rank owner or admin. only then should the route /dashboard/users/settings be used. if the user does not have the rank, he should be redirected to the /dashboard page. the other routes should only have a query whether the user is logged in.
export { default } from "next-auth/middleware"
export const config = { matcher: ["/dashboard", "/dashboard/users/settings", "/dashboard/profile/settings"] }Answered by Northeast Congo Lion
callbacks: {
authorized: ({ req, token }: { req: NextRequest, token: any }) => {
const path = req.nextUrl.pathname;
if (path.startsWith('/admin')) {
return token?.user?.role == 'admin'
}
return token?.user?.connected ?? false;
},
}126 Replies
tryt his
callbacks u can check if the user has admin
check if path contains say
/users/settings or equals it, then check rank and go from there.i've done similar things with protecting
/admin against normal users.MikeOP
Yes, I have seen this. But it doesn't explain how I can say that only /dasboard/users/settings should be checked with a rank
@Mike Yes, I have seen this. But it doesn't explain how I can say that only /dasboard/users/settings should be checked with a rank
Northeast Congo Lion
you can check request
and see pathname i am sure.
so check pathname
MikeOP
okay, i understand
Northeast Congo Lion
then check user info
im not on my laptop rn but if i remember
i will dig out my example i have
becos it does what ur trying to do
MikeOP
okay, take your time. if youre on the pc then send it please
Northeast Congo Lion
callbacks: {
authorized: ({ req, token }: { req: NextRequest, token: any }) => {
const path = req.nextUrl.pathname;
if (path.startsWith('/admin')) {
return token?.user?.role == 'admin'
}
return token?.user?.connected ?? false;
},
}Answer
MikeOP
Thank you very much. what does the connected in your user do with you? can i somehow define on which page he should be redirected if he does not come to the /admin page?
Northeast Congo Lion
yeah u can redirect from middleware i think
@Mike Thank you very much. what does the connected in your user do with you? can i somehow define on which page he should be redirected if he does not come to the /admin page?
Northeast Congo Lion
it is just some extra info for our users as the dashboard has like a
connect ur accountso it is extra infoI pass to user object on login, don't worry.
MikeOP
import { withAuth } from "next-auth/middleware";
export default withAuth({
callbacks: {
authorized: ({ req, token }) => {
const path = req.nextUrl.pathname;
if (path.startsWith("/dashboard/users/settings")) {
return token?.user?.role == "admin";
}
return !!token;
},
},
});
export const config = {
matcher: ["/dashboard", "/dashboard/profile/settings"],
};I now have it like this, but the problem is that the user can still call up the route /dashboard/users/settings when he is logged out. no data is displayed anymore, but he can call it up
Northeast Congo Lion
are u adding role to user on login?
MikeOP
yes
Northeast Congo Lion
also try this
export const config = {
matcher: [
'/dashboard/:path*'
]
}MikeOP
let me try this i will answer you in a few minutes
but now i cant open the /dashboard/users/settings but he has the admin role. you can see it here
Northeast Congo Lion
debug your logic,
is the path.startsWith being triggered
is the path.startsWith being triggered
check if token?.user?.role does == admin
MikeOP
Yes, i will check it
Northeast Congo Lion
my advice is always this
rubber duck it
e.g talk to yourself about the code lol
as you do go through the logic and break it down
problems are easier to tackle if they are smaller 🙂
MikeOP
Okay, i have found the rror. now it works. Now i need to check how i can do a redirect. because if i have no rights for the site it redirects me to the login first. and then from the login to the dashboard because i am logged in
Northeast Congo Lion
well
if not admin, redirect to
/dashboardand then next-auth will check again if the user is actually logged in
next-auth will boot them to the login page u configured in next auth options
MikeOP
How can I make a redirect to /dashboard here if it does not have the admin or owner role?
import { withAuth } from "next-auth/middleware";
export default withAuth({
callbacks: {
authorized: ({ req, token }) => {
const path = req.nextUrl.pathname;
if (path.startsWith("/dashboard/users/settings")) {
return token?.rank == "admin" || token?.rank == "owner";
}
return !!token;
},
},
});
export const config = {
matcher: [
'/dashboard/:path*'
]
}Northeast Congo Lion
i believe i u return false in authorized, it will consider not logged in
MikeOP
But there must be a way. because it looks really crap when i first get to the login page and then to the dashboard. i understand what you mean.
Northeast Congo Lion
maybe u can share a screen-recording
so i can see exact issue
oh actually i see.
are you using nextjs app router?
MikeOP
yes
but i can do screen recording if you need
Northeast Congo Lion
please do
MikeOP
As you can see I have no rights to access this page this works correctly. But I am then redirected to the login page. Since I am logged in, the login page redirects me to the /dashboard page. But I would like to be redirected directly to the /dashboard page if I have no rights to access the page and am still logged in without first seeing the login page.
Northeast Congo Lion
ah i see
MikeOP
yes 🙂
Northeast Congo Lion
can u try doing
return NextResponse.redirect(new URL('/dashboard', req.url)); somerthing like thise.g if they are logged in but no admin
MikeOP
you mean like this?
import { withAuth } from "next-auth/middleware";
export default withAuth({
callbacks: {
authorized: ({ req, token }) => {
const path = req.nextUrl.pathname;
if (path.startsWith("/dashboard/users/settings")) {
return token?.rank == "admin" || token?.rank == "owner";
}
return NextResponse.redirect(new URL('/dashboard', req.url));;
},
},
});
export const config = {
matcher: [
'/dashboard/:path*'
]
}Northeast Congo Lion
i mean this will work if not admin
but u do need to adjust logic
so try it, and see if it works!
MikeOP
i have try it like this
import { withAuth } from "next-auth/middleware";
import { NextResponse } from "next/server";
export default withAuth({
callbacks: {
authorized: ({ req, token }) => {
const path = req.nextUrl.pathname;
if (path.startsWith("/dashboard/users/settings")) {
if (token?.rank !== "admin" || token?.rank !== "owner") {
return NextResponse.redirect(new URL("/dashboard", req.url));
}
}
return !!token;
},
},
});
export const config = {
matcher: ["/dashboard/:path*"],
}; but now i can just go to the admin page without any rightsMikeOP
and there is no description on the nextauth docs about this
Northeast Congo Lion
Yes I saw a GitHub post about making next auth redirect a proper solution and not just a hack
Another option are you aware of nested layout?
MikeOP
But his option should be work but i dont got an redirect
import { withAuth } from "next-auth/middleware";
import { NextResponse } from 'next/server';
export default withAuth({
callbacks: {
authorized: ({ req, token }) => {
const path = req.nextUrl.pathname;
console.log(token?.rank);
if (path.startsWith("/dashboard/users/settings")) {
if(token.rank !== "admin" || token.rank !== "owner") {
console.log("not valid");
return NextResponse.redirect(new URL('/dashboard', req.url));
}
}
return !!token;
},
},
});
export const config = {
matcher: [
'/dashboard/:path*'
]
}and i got the console.log not valid
but the redirect doesnt work
Northeast Congo Lion
I am not entirely sure if it can redirected from next auth
It was just an idea
You can use layout.js
And check for session
For all admin route
So place a layout.js inside the settings route segemeny
and then check and do redirect there
Northeast Congo Lion
Give it a go then
@Mike I don’t want to give you all the answers 🙂
Otherwise you won’t learn
so I’m here if ur super super stuck but try it urself man
MikeOP
ok
Northeast Congo Lion
I have been coding for 6 years. Best advice I can give is just try
That’s how you become better
MikeOP
ive been coding for 12 years
at first erp systems for microsoft
like microsoft dynamics nav
and then ive done my webmaster
Northeast Congo Lion
Nice
MikeOP
but there we only learned js basics and php
Northeast Congo Lion
Yes next with
auth*
Is not for beginners haha
It can be a pain tbh
NextAuth that is
MikeOP
i am not beginner in web 🙂
ive done my webmaster 🙂
Northeast Congo Lion
I mean if ur new to nextjs etc
MikeOP
yes there i am new
Northeast Congo Lion
It can all be learned tho
MikeOP
i used vuejs and nodejs before this
Northeast Congo Lion
Nice I have c# and NodeJS but love c#
NodeJS not so much
MikeOP
i know powershell, and microsoft sql, java, php, vuejs, node, C/Al, A/L 🙂
Northeast Congo Lion
Next auth should be a walk in the park then
MikeOP
we built rest apis with powershell at microsoft
Northeast Congo Lion
But I will say
Next Auth docs
Is not brilliant 😦
I have lots of colleagues and friends complain on the docs
@Northeast Congo Lion Is not brilliant 😦
MikeOP
yes thats my reason why i asked for this
Northeast Congo Lion
My suggestion would be to use nested layout
As workaround
MikeOP
okay
i will try it thanks
Northeast Congo Lion
Use server session
And check if role is admin
If not redirect to dashboard
MikeOP
okaym i will do it
Northeast Congo Lion
So is it just
MikeOP
thanks
Northeast Congo Lion
Settings that is protected
Or users too
/users/settings
You can place layout at either user level or settings level for segment