Permission based access with middleware
Answered
Northeast Congo Lion posted this in #help-forum
Northeast Congo LionOP
Hello, basically I try to grant access to a particular type of users (admin). To check if a user is an admin or not, when the user logs in, he receives his token, then with his token I make another request to get his role and decide to grant access to the app or not. I works and that makes the login work in a two-step process. The problem is, before granting access to a particular path say "/dashboard" I wrote the a function to get the user's role and I added it to my middleware. But now every time the user navigates to a path, his role is fetched every time (and that's an unnecessary network call) and I would like to avoid it since the role was fetched when the user was logging in.
Is there a way I can cache the result of the fetching of the user role info and reuse it so that my middleware doesn't make network call on every navigation ? Or did I implement it the wrong way.
PS : I did the session management myself and skipped third party librairies and here the NextJS app for the auth part depend on an external API so that's why I talked about fetching a user role and that's why the auth process works this way. The token I receive doesn't have the role in it so I have to use it to get more info about the user.
Thanks for your help
Is there a way I can cache the result of the fetching of the user role info and reuse it so that my middleware doesn't make network call on every navigation ? Or did I implement it the wrong way.
PS : I did the session management myself and skipped third party librairies and here the NextJS app for the auth part depend on an external API so that's why I talked about fetching a user role and that's why the auth process works this way. The token I receive doesn't have the role in it so I have to use it to get more info about the user.
Thanks for your help
Answered by Alfonsus Ardani
Like going from login to /stats, from /stats to /dashboard, from /dashboard to /x, the role is fetched that many times.
So I'm looking for a way to do this only once, preferably when the user logs in.
You can create a JWT that stores the user's role at login
22 Replies
Barbary Lion
you can use react's cache function
Northeast Congo LionOP
Ow thanks mate, I will try it and get back to you
I dont think react's cache can pass data from middleware to components
I think you need to store the data from middleware in a header
and you can consume it later in server compoennts and passed to a client component
Northeast Congo LionOP
@Alfonsus Ardani Can you explain better your answer ?
In a header of the fetch ? or when I get the response back ? and will it persist and be not accessible by javascript like cookies in NextJS (httpOnly).
Cause like I said, I already fetch the role when the user logs in to either create a session or deny access due to lack of privileges (since I don't have control of the info in token I receive).
And then when the user navigates to say /stats the middleware kicks in since it runs on each navigation, but when it does the role is fetched again, and on every navigation. Like going from login to /stats, from /stats to /dashboard, from /dashboard to /x, the role is fetched that many times.
So I'm looking for a way to do this only once, preferably when the user logs in.
In a header of the fetch ? or when I get the response back ? and will it persist and be not accessible by javascript like cookies in NextJS (httpOnly).
Cause like I said, I already fetch the role when the user logs in to either create a session or deny access due to lack of privileges (since I don't have control of the info in token I receive).
And then when the user navigates to say /stats the middleware kicks in since it runs on each navigation, but when it does the role is fetched again, and on every navigation. Like going from login to /stats, from /stats to /dashboard, from /dashboard to /x, the role is fetched that many times.
So I'm looking for a way to do this only once, preferably when the user logs in.
assuming that your middleware is in middleware.ts, it is not supposed to do long await operations like fetching datas from external source
but if you insist
you can store it in the header where you can get it in next.js pages and layouts via
await headers()
Like going from login to /stats, from /stats to /dashboard, from /dashboard to /x, the role is fetched that many times.
So I'm looking for a way to do this only once, preferably when the user logs in.
You can create a JWT that stores the user's role at login
Answer
then at the middleware you can decode the JWT and get the role. Set header something like 'x-app-auth-role' and proceed through the Request.
Then at page.js or layout.js you can just
Then at page.js or layout.js you can just
(await headers()).get('x-app-auth-role')
alternatively you can also decode the JWT directly at page.js or layout.js via
await cookies()
and returning the sessionNortheast Congo LionOP
Okay I see thanks mate, can I just set the header and have it stick to subsequent request without being accessible by javascript ?
I don't want to the fetch in the middleware by the way that's why i prefer the role to stick or get stored in a secure place, like the one you highlighted (I think)
if you want something that "stick to subsequent request", then store a cookie. preferable one with the httpOnly and secure flag
cookie will be sent for every request by the browser given its the same domain and not expired
Northeast Congo LionOP
Okay so you're that if I go with the header function that will just give me access to the role inside of the components and if its just for the requests I should use a cookie instead right ?
@Northeast Congo Lion Okay so you're that if I go with the header function that will just give me access to the role inside of the components and if its just for the requests I should use a cookie instead right ?
you could just read the cookie and verify and extract the role data and pass it to the component
cookies are stored in the headers soo
Northeast Congo LionOP
Yeah I get it, I mean It was just to understand clearly the other option. I get what you said, and it's an effective idea, thank you for your time.
@Alfonsus Ardani I dont think react's cache can pass data from middleware to components
Barbary Lion
You're right, react's cache function is solely for the react rendering process. Middleware runs in a different environment and context