A very basic thing that can not be done right using NextAuth?

I have an app that uses DB sessions. I've got an /admin route that I want to protect using a Next.js middleware by checking the user's role, but I can't do this because I don't have access to 'user' obj. How can I do this right without having to copy-paste a block of getServerSideProps?
30 Replies
cje
cje2y ago
middleware runs on the server so you have access to the server session https://next-auth.js.org/tutorials/securing-pages-and-api-routes#securing-api-routes
Securing pages and API routes | NextAuth.js
You can easily protect client and server side rendered pages and API routes with NextAuth.js.
hyperzone
hyperzoneOP2y ago
You can't access the session in middleware.ts i need to correct myself, I'm trying to protect admin pages not api routes api routes are protected by tRPC anyways
cje
cje2y ago
Oh then I misunderstood
hyperzone
hyperzoneOP2y ago
Yeah I apologize
cje
cje2y ago
Depending on your needs, you might be able to use a shared layout Put a hook in it that checks for a role, and a component that doesn’t render children unless that role exists
hyperzone
hyperzoneOP2y ago
And redirect instead to a 404 also right?
cje
cje2y ago
Sure
hyperzone
hyperzoneOP2y ago
that's a great idea thank you
cje
cje2y ago
Or just render “you’re not allowed to see this”
hyperzone
hyperzoneOP2y ago
yeah correct
cje
cje2y ago
Either one is fine, depends what fits best with your project as a whole I guess
hyperzone
hyperzoneOP2y ago
Thanks 🙂 So I did this, in the shared layout I called useSession and checked for session.user.role === 'ADMIN' in a useEffect that runs on mount. But the issue is that for the first second session.user is null so it will not satisfy the condition
cje
cje2y ago
Where is your data coming from? I would do like const isAuthed = useSomeHook And then if (!isAuthed) don’t render anything
hyperzone
hyperzoneOP2y ago
I need the data that's in the nextauth session specifically the role that i store in the user object
cje
cje2y ago
No I mean like the data that is displayed on the page Make the fetching of that conditional Only fetches if user is airbed Authed
hyperzone
hyperzoneOP2y ago
for anyone seeing this in the future, I think this is the best solution (inside a custom layout - for example if you have a layout for /admin/* pages)
const { data: session, status } = useSession();
const router = useRouter();

if (
status !== "loading" &&
session &&
session.user &&
session.user.role !== "ADMIN"
) {
router.push("/404");
}

if (status === "loading") {
return <div>Loading...</div>;
}
const { data: session, status } = useSession();
const router = useRouter();

if (
status !== "loading" &&
session &&
session.user &&
session.user.role !== "ADMIN"
) {
router.push("/404");
}

if (status === "loading") {
return <div>Loading...</div>;
}
Ambushfall
Ambushfall2y ago
@hyperzone Sorry to bother you, however this is not auth related, it's authorization related. And Authorization isn't and will not be handled by NextAuth. (At the least for the time being - it's handled by the Oauth providers or you) Also for the code was it not easier to write?
status !== "loading" && session?.user?.role !== "ADMIN" ? router.push("/404") : false
status !== "loading" && session?.user?.role !== "ADMIN" ? router.push("/404") : false
hyperzone
hyperzoneOP2y ago
How asking about the behavior of the useSession hook that NextAuth provides isn't related to NextAuth?
Ambushfall
Ambushfall2y ago
You've originally asked about Next.js middleware, which is the correct direction, and mentioned that you cannot do it as you have no Context or Session, I've noted that this isn't usually handled through NextAuth, rather by other middleware, that is all. Your question's title was pertaining to NextAuth, while it is possible to authorize via NextAuth, it's not usually done in such a way, it can be done to keep things simple however, but the title indicated as if NextAuth was not working in some way, which just isn't true. Or the very least, that's how I had perceived it, and chimed in on a note to help clarify things, hope you didn't misunderstand me : 3
hyperzone
hyperzoneOP2y ago
I really don't understand how your comments benefit this conversation? NextAuth, like stated in their docs, doesn't give you access to the session in middleware.ts because of reasons and I needed a solution to let me achieve something similar to thata
Ambushfall
Ambushfall2y ago
Questions exist to be answered, and when someone isn't sure of what they're asking about, I'm quite free to chime in and fill in the blanks or add additional information that I find relevant to the topic. As each of my comments are quite relevant to what you were asking. I've also made sure to add beneficial shortening of code with an example. It's not all about getting something, it's mostly about understanding and learning, sharing knowledge. Middleware provides an example of this within their docs:
import { withAuth } from "next-auth/middleware"

export default withAuth(
// `withAuth` augments your `Request` with the user's token.
function middleware(req) {
console.log(req.nextauth.token)
},
{
callbacks: {
authorized: ({ token }) => token?.role === "admin",
},
}
)

export const config = { matcher: ["/admin"] }
import { withAuth } from "next-auth/middleware"

export default withAuth(
// `withAuth` augments your `Request` with the user's token.
function middleware(req) {
console.log(req.nextauth.token)
},
{
callbacks: {
authorized: ({ token }) => token?.role === "admin",
},
}
)

export const config = { matcher: ["/admin"] }
I don't think it's necessary to act in such a way when you're reaching out for help.
hyperzone
hyperzoneOP2y ago
I know exactly what I'm asking about and you're acting weird If you would read the question you'd see that I asked about DB sessions, and the example you provided is related to jwts and if you'd read the docs, you'd see they clearly state that
Ambushfall
Ambushfall2y ago
Yes, it's used for JWT as NextAuth has no way of accessing the DB or the User yet. Which is why I've mentioned you can use other middleware for this, or authorize it manually by doing what you've done already.
hyperzone
hyperzoneOP2y ago
None of your comments is relevant to this question, you didn't even read it and you provide incorrect information so stop commenting on this already, we literally resolved this yesterday there is valuable information that is buried already because of your irrelevant comments
Ambushfall
Ambushfall2y ago
You're trying to authorize with an authentication middleware. Authorization is done by you, in any way you like as you structure your own database and your own App logic. NextAuth for all of it's intents and purposes should not have anything to do with DB Authorization strategies. Your question was regarding auth, not authorization. I've read your question, but the question itself made no sense to me so I guessed you have no clue what you're going on about, and why would you be asking these things? It's literally just up to you how you authorize. Learn to be polite.
Ambushfall
Ambushfall2y ago
Theo - t3․gg
YouTube
Authentication: It’s Easier Than You Think
I get a LOT of questions about auth so I figured it was time for a video! We talk all about authentication and authorization. Watch rants like this live on https://twitch.tv/theo LIVE EVERY WEDNESDAY AT ROUGHLY 1PM PT Twitch: https://twitch.tv/theo Twitter: https://twitter.com/t3dotgg Instagram: https://instagram.com/fakiebigfoot Everywhere els...
hyperzone
hyperzoneOP2y ago
THE QUESTION MAKES PERFECT SENSE AND WAS RESOLVED YESTERDAY You copy pasting code from docs does not help in any way Pretentious and wrong, worst combination Why do you chime in to every thread mentioning NextAuth with "This is related to authorization, not auth, please delete the NextAuth flag"????? this is straight up weird
Ambushfall
Ambushfall2y ago
My understanding of authorization might be flawed, but I chimed in as from my perspective, Authorizing should be done by you in a custom way specifically for your app, I don't think NextAuth should have any say in that. All I'm trying to do is help out, that's about it.
hyperzone
hyperzoneOP2y ago
If you want to help, read the question and don't chime in and tell people they're wrong and don't understand what they're asking about, when it's you who doesn't understand
Ambushfall
Ambushfall2y ago
My bad for misunderstanding, were you able to solve the previous questions you've asked as well? Routing after Auth, etc.
Want results from more Discord servers?
Add your server