Protecting next routes, client side? (confused)
Unanswered
Pacific saury posted this in #help-forum
Pacific sauryOP
Gm gm, I'm new here, this was the only place I could think of coming since I'm trying to get into dev thanks to Theo channel. I built my app and now I'm facing an issue that will probably cost me a lot of dev hours.
I can't protect my routes. I don't have user auth, I just need the app to do some crud operations, I created routes for it, but now I can't prevent others from calling these endpoints because, it seems to me, that since these routes are being fetched client side, there's no way to setup some basic auth token for the fetch, since it would be displayed on client side itself. (figured this out cause my bearer token was undefined and I realised that client can't access .env files, which makes total sense)
So I've exhausted my VERY LIMITED noob knowledge of next js / ts / react, I've come to realize probably my solution exists on server side components? But I'm, super confused since the interaction that originates the fetch (ex, press a button) happens on client side.
For the love of God, can someone point me to a simple solution? I'm searching for tutorials but I can only find route protection via next-auth, this is not what I want I dont have user authentication, I just want to protect the app endpoints to only be usable, well, by the app itself.
Maybe I completely missed the point of next js and this is the most stupid question ever 😦
I can't protect my routes. I don't have user auth, I just need the app to do some crud operations, I created routes for it, but now I can't prevent others from calling these endpoints because, it seems to me, that since these routes are being fetched client side, there's no way to setup some basic auth token for the fetch, since it would be displayed on client side itself. (figured this out cause my bearer token was undefined and I realised that client can't access .env files, which makes total sense)
So I've exhausted my VERY LIMITED noob knowledge of next js / ts / react, I've come to realize probably my solution exists on server side components? But I'm, super confused since the interaction that originates the fetch (ex, press a button) happens on client side.
For the love of God, can someone point me to a simple solution? I'm searching for tutorials but I can only find route protection via next-auth, this is not what I want I dont have user authentication, I just want to protect the app endpoints to only be usable, well, by the app itself.
Maybe I completely missed the point of next js and this is the most stupid question ever 😦
21 Replies
@Pacific saury Welcome do the dev world! What you're trying to do is actually difficult to do with nextjs specifically because of the serverless nature of api routes. One thing you might try is to set your CORS headers to only allow your domain to call your api routes.
https://nextjs.org/docs/app/building-your-application/routing/router-handlers#cors
https://nextjs.org/docs/app/building-your-application/routing/router-handlers#cors
But I'd be curious to here your usecase and why you want to lockdown the API
But just to say it too, you may be on the right track with server components. The question on how to fetch more/different data based on the input from the front end. There are 2 ways of doing this, you can use server actions or maybe better to use routes to update things. For example with routes lets say you have
/products/category/shirts if you have a catch-all route /products/[...category].jsx you can fetch different data based on the category. This will all happen on the server component and hydrate/refresh on the page dynamically@andrewscofield <@1044646319337242726> Welcome do the dev world! What you're trying to do is actually difficult to do with nextjs specifically because of the serverless nature of api routes. One thing you might try is to set your CORS headers to only allow your domain to call your api routes.
https://nextjs.org/docs/app/building-your-application/routing/router-handlers#cors
Pacific sauryOP
Yes, I implemented this but chat gpt says it can be spoofed
@andrewscofield But just to say it too, you may be on the right track with server components. The question on how to fetch more/different data based on the input from the front end. There are 2 ways of doing this, you can use server actions or maybe better to use routes to update things. For example with routes lets say you have `/products/category/shirts` if you have a catch-all route `/products/[...category].jsx` you can fetch different data based on the category. This will all happen on the server component and hydrate/refresh on the page dynamically
Pacific sauryOP
Thank you. I haven't tried server actions yet.
Server actions probably solve it the easiest.
Going to try it out. Thanks you!
Server actions probably solve it the easiest.
Going to try it out. Thanks you!
if you're making an app that needs to have user generated and private content then you can protect your routes using middleware and check if a user is authenticated and only allow requests if they are. Otherwise if the content is publicly available there's no point in protecting your api routes since visitors can see the data anyways
@not-milo.tsx if you're making an app that needs to have user generated and private content then you can protect your routes using middleware and check if a user is authenticated and only allow requests if they are. Otherwise if the content is publicly available there's no point in protecting your api routes since visitors can see the data anyways
Pacific sauryOP
thank you, I'm looking into middlware right now
I'm curious what your project is? Trying to understand how the data is private yet accessible to anyone on your app. You mentioned a bearer token being accessible on client side so that leads me to believe you are using an outside service API and you want to protect that key. If that is the case, let us know, we can walk you through that, it is very typical and easy to solve with next.js
@andrewscofield I'm curious what your project is? Trying to understand how the data is private yet accessible to anyone on your app. You mentioned a bearer token being accessible on client side so that leads me to believe you are using an outside service API and you want to protect that key. If that is the case, let us know, we can walk you through that, it is very typical and easy to solve with next.js
Pacific sauryOP
Im implementing the routes and the endpoints updated mongoDB cloud.
I need to make the serverless functions private, thats my goal. Unfortunately I cant even pass a token in the fetch command, when I log the headers on the server side theres not authorization key in the headers
I need to make the serverless functions private, thats my goal. Unfortunately I cant even pass a token in the fetch command, when I log the headers on the server side theres not authorization key in the headers
Can you not just create an API route as an in between between client and the mongodb cloud?
Client fetch > API route > mongodb
Like this:
Client: fetch('/api/posts')
API route: You can can make mongodb connection using private token from environment variables
Client fetch > API route > mongodb
Like this:
Client: fetch('/api/posts')
API route: You can can make mongodb connection using private token from environment variables
Pacific sauryOP
this is what I did, but how to I protect the route? anyone calling this route would gain access to the database
this is what I dont understand
for instance
try {
//let's lock this Raffle while the request is being processed
// also check if there is no global override for this raffle, if there is do not process the request
setLockedRaffle(true);
//await new Promise((r) => setTimeout(r, 1000)); // wait for 1 second
const response = await fetch("/api/updateTicket", {
// replace '/api/update-route' with your route
method: "PUT",
headers: {
"Content-Type": "application/json",
Auth: `Bearer 99Problems`,
},
body: JSON.stringify({
address: owner,
raffle: raffleID,
updateType: "TO_NULL",
}),
});`this "99Problems" can be seen in the network tools from Chrome
so again, anyone can gain access
this is driving me insane
@Pacific saury Gm gm, I'm new here, this was the only place I could think of coming since I'm trying to get into dev thanks to Theo channel. I built my app and now I'm facing an issue that will probably cost me a lot of dev hours.
I can't protect my routes. I don't have user auth, I just need the app to do some crud operations, I created routes for it, but now I can't prevent others from calling these endpoints because, it seems to me, that since these routes are being fetched client side, there's no way to setup some basic auth token for the fetch, since it would be displayed on client side itself. (figured this out cause my bearer token was undefined and I realised that client can't access .env files, which makes total sense)
So I've exhausted my VERY LIMITED noob knowledge of next js / ts / react, I've come to realize probably my solution exists on server side components? But I'm, super confused since the interaction that originates the fetch (ex, press a button) happens on client side.
For the love of God, can someone point me to a simple solution? I'm searching for tutorials but I can only find route protection via next-auth, this is not what I want I dont have user authentication, I just want to protect the app endpoints to only be usable, well, by the app itself.
Maybe I completely missed the point of next js and this is the most stupid question ever 😦
I can't protect my routes.Yes you can, i believe in you
(figured this out cause my bearer token was undefined and I realised that client can't access .env files, which makes total sense)Client can access .env files
But I'm, super confused since the interaction that originates the fetch (ex, press a button) happens on client side.Server Actions creates a route that obfuscate request URL and make all request into POST maybe you can look into that
@alfon > I can't protect my routes.
Yes you can, i believe in you
> (figured this out cause my bearer token was undefined and I realised that client can't access .env files, which makes total sense)
Client can access .env files
> But I'm, super confused since the interaction that originates the fetch (ex, press a button) happens on client side.
Server Actions creates a route that obfuscate request URL and make all request into POST maybe you can look into that
Pacific sauryOP
hi! I'm looking into server actions rn, I guess thats the best way to have the cli call server functions?
@Pacific saury hi! I'm looking into server actions rn, I guess thats the best way to have the cli call server functions?
the question regarding if its the best or not is all depends on your use case
What is the bearer token for? To prevent anyone from being able to call and API route you can setup CSRF
https://github.com/j0lv3r4/next-csrf
Essentially, as the page loads your server uses a server only environment variable to generate a token. You send that token along with any requests to your API. Your API route checks for the CSRF token and checks that it's valid before it runs the API route. This helps ensue that the route came from your front end because the CSRF token was signed and generated using your secret key.
This library I linked to is just one way, there are other methods including
https://github.com/j0lv3r4/next-csrf
Essentially, as the page loads your server uses a server only environment variable to generate a token. You send that token along with any requests to your API. Your API route checks for the CSRF token and checks that it's valid before it runs the API route. This helps ensue that the route came from your front end because the CSRF token was signed and generated using your secret key.
This library I linked to is just one way, there are other methods including
iron-session