Need help with specific auth usecase along with route protection
Unanswered
Kunal Jain posted this in #help-forum
Hello,
I am new to the Next ecosystem and would mean a lot if you read this to the end and please drop a little guidance!
I have a Node Express backend server which has a otp validation route /validate-otp and on success this route returns the access token and sets the refresh token as http only cookies. I have another end point /token which is to be hit when access token expires, on the backend in the controller of this route refresh token is extracted from the cookies, validated and accordingly new access token is generated and returned. This way I tend to keep my access token short lived and store them in application state and refresh tokens are long lived to maintain long user sessions.
Now this backend server is common to multiple frontend applications, one of them is in React and the new one that we're currently working on is on Next 13 with App router setup. In the React project how we manage user sessions is, we basically hit the /token API as soon as the user lands on the application and wait for it's response, if the response is a success that means we got a new access token and accordingly authenticate the user and if not we redirect the user to signin page. Our route protection also works accordingly.
The issues we're facing with Next 13:
- The cookie that backend sets on /validate-otp route is not getting set in case of Next. I am assuming this has to do with server side?
- I am not able to acheive route protection properly, I don't know if I should be using middleware or how exactly would the entire flow work. I did try a few things but nothing seemed to work. I have server/client components both.
- My basic requirement is, unauthenticated user tries accessing any private route should get redirected to signin page and vice versa, user once authenticaed should have a persisting session across reloads etc using the /token API. The application should show an overall loader while it figures out whether the user is authenticated or not.
Thanks!
I am new to the Next ecosystem and would mean a lot if you read this to the end and please drop a little guidance!
I have a Node Express backend server which has a otp validation route /validate-otp and on success this route returns the access token and sets the refresh token as http only cookies. I have another end point /token which is to be hit when access token expires, on the backend in the controller of this route refresh token is extracted from the cookies, validated and accordingly new access token is generated and returned. This way I tend to keep my access token short lived and store them in application state and refresh tokens are long lived to maintain long user sessions.
Now this backend server is common to multiple frontend applications, one of them is in React and the new one that we're currently working on is on Next 13 with App router setup. In the React project how we manage user sessions is, we basically hit the /token API as soon as the user lands on the application and wait for it's response, if the response is a success that means we got a new access token and accordingly authenticate the user and if not we redirect the user to signin page. Our route protection also works accordingly.
The issues we're facing with Next 13:
- The cookie that backend sets on /validate-otp route is not getting set in case of Next. I am assuming this has to do with server side?
- I am not able to acheive route protection properly, I don't know if I should be using middleware or how exactly would the entire flow work. I did try a few things but nothing seemed to work. I have server/client components both.
- My basic requirement is, unauthenticated user tries accessing any private route should get redirected to signin page and vice versa, user once authenticaed should have a persisting session across reloads etc using the /token API. The application should show an overall loader while it figures out whether the user is authenticated or not.
Thanks!
2 Replies
bump ^
Barbary Lion
@Kunal Jain Hi,
do you want to set the cookie in a server-side component or client-side?
If you want to set the cookie server-side follow the documentation:
https://nextjs.org/docs/app/api-reference/functions/cookies
If you want to set the cookie client-side return the cookie from your api and set it via next-client-cookies
For the middleware, follow the documentation:
https://nextjs.org/docs/pages/building-your-application/authentication#protecting-routes-with-middleware
Basically what you want to do is creating a middleware.js/.ts file in the project's root directory. The logic for the redirection could look like this:
export function middleware(request) {
//get current user
if (!user && request.nextUrl.pathname.startsWith('/path')) {
return Response.redirect(new URL('/login', request.url))
} else if (user && request.nextUrl.pathname.startsWith('/login')) {
return Response.redirect(new URL('/path', request.url))
}
}
What this does, is checking if there is a current user.
If there isn't a user but he tries to go to /path, he gets redirected to /login and vice-versa
do you want to set the cookie in a server-side component or client-side?
If you want to set the cookie server-side follow the documentation:
https://nextjs.org/docs/app/api-reference/functions/cookies
If you want to set the cookie client-side return the cookie from your api and set it via next-client-cookies
For the middleware, follow the documentation:
https://nextjs.org/docs/pages/building-your-application/authentication#protecting-routes-with-middleware
Basically what you want to do is creating a middleware.js/.ts file in the project's root directory. The logic for the redirection could look like this:
export function middleware(request) {
//get current user
if (!user && request.nextUrl.pathname.startsWith('/path')) {
return Response.redirect(new URL('/login', request.url))
} else if (user && request.nextUrl.pathname.startsWith('/login')) {
return Response.redirect(new URL('/path', request.url))
}
}
What this does, is checking if there is a current user.
If there isn't a user but he tries to go to /path, he gets redirected to /login and vice-versa