Getting url parameter from react to node - javascript

I have a node server running on localhost:5000 and I'm able to get a hash sent in the url with the following code:
app.get('/:hash', function(req, res) {
const id = req.params.hash;
});
I then also have a front end react app running on http://localhost:3000, and a proxy setup in package.json, but when I vistor http://localhost:3000/somehash I'm not able to retrieve the value some hash. Is there a step I'm missing to be able to get that value from react and pass it to node?
Thanks!
Background:
I'm creating a url shortener. User visits the react app and inputs a url to be shortened. Node returns a hash the user can use and share with others. Users who are given the hash url can visit and be redirected to the original url. Works fine on localhost:5000(node) but doesn't work on localhost:3000 (react). For some reason node isn't picking up the hash from react when the user first visits the page.

You must configure a route to receive the hash on react too.
Then, the react code can fetch the backend and get the URL from the hash.
And only then, the react can perform the redirection with window.location = URL
If you are using react-router-dom you can create the route like this:
<Route path="/app/:hash" exact component={YourComponent} />
Then, in YourComponent you can get the hash like this:
const {hash} = this.props.match.params;

Your backend is listening on port 5000 not 3000.
When you navigate to localhost:3000/somehash, you're asking your frontend to load the page somehash which needs to correspond to a route in React.
If you want to access the server's API on port 5000 through your React app on port 3000, you need to write the corresponding feature. For example an HTTP request to your localhost. It may look like this
// SomewhereInYourReactApp.js
const someHash = 'hello_world';
fetch(`localhost:3000/${someHash}`)
.then(response => response.json())
.then(myJson => {
console.log(JSON.stringify(myJson));
});

Related

Is there a way to serve files to browser and data to rest requests using the same endpoint?

I've followed this 7 hour tutorial on creating a blog almost to. There is one step that I skipped, because I did not want to use the separate client/server hosting that the tutorial suggests. Instead, I have a single heroku server that serves the client out of the public server:
const app = express();
app.use(express.static('public'))
app.use('/posts', postRoutes);
app.use('/user', userRoutes)
You can see that the app also serves some rest requests to the /posts and /user paths. However, the tutorial also led me to add these paths into the url client-side.
For example, you can access my app at (https://blog-tutorial-888.herokuapp.com), but you will be immediately "redirected" to (https://blog-tutorial-888.herokuapp.com/posts).
I say "redirected" because on the client side, it appears that you are at that site, and the purpose is so that you can do things like navigate to the next page, which will be at (https://blog-tutorial-888.herokuapp.com/posts?page=2).
But if you were to actually go to these links, or refresh the page, you will be hit with the result of the rest request, which is a giant block of text (and this is obviously because I have app.use('/posts', postRoutes)).
Is there a way to get around this somehow? Somehow serve both the html and the rest request at this endpoint?
To have a single server that severs the front and data trough a REST API, you would need to differentiate the paths, for example by adding an /api to urls for getting data, like so:
app.use('/api/posts', postRoutes);
app.use('/api/user', userRoutes);
And then below all your /api handlers add following lines so that for every other request you send that HTML that would load React bundle:
app.get("/*", (req, res) => {
// Make sure it's the correct path to the build folder
res.sendFile(path.join(__dirname, "../client/build/index.html"));
});
Of course don't forgot to add /api in your front end query urls as well, not the routes setup:
fetch("/api/posts")
// or
axios.get("/api/posts")

Given a user's request for the index page ('/'), how do we intercept and run a function on the server in Next.js?

Is there a way using a middleware function or some other method in Next.js to see if a user is attempting to go to the home page?
What I'm trying to do basically is intercept a user's request for the home page. Intercepting a URL request is relatively easy to do with Next.js middleware. For example, if you want to see if a user is trying to access a single page called /login, you can access the request url like so:
export default async function middleware(req, res){
const url = req.url;
if (url.includes('/login')){
// carry out action
}
}
However, how can this be done for a home page URL (e.g https://fakewebsite.com/ or in development, localhost:3000)?
I think you can use the middleware introduced in nextjs version 12 to accomplish this. There you can introduce a config for matching URLs and have access to user's request:
Next.JS middleware.
The problem with what you have is that you're missing the config export from your middleware, inside which you can specify the matcher:
// middleware.js
export const config = {
matcher: '/',
}
This will only allow home requests to reach your middleware.

random `/undefined ` addition to request link from .env files

I am building a react app and i have hooked it up to my API. I was trying to see if the API could communicate with the app and they do but there is a problem. I want to use my .env variables to connect to my api but when im trying to make a request a random /undefined shows up at the link im trying to reach. Example:
what i want the app to request : PATCH https://myapi.com/1/1/false
the link the app actually uses : PATCH https://myapi.com/undefined/1/1/false
I figured out it was the .env file's fault because when i changed my value on the codes app :
from: const url = process.env.CONNECTION_URL
to : const url = "https://myapi.com"
it works like a charm. Is there anything i can do to remove the /undefined from the link ?

how to hide nextjs api routes from being directly accessible through url?

Is there any way to make next.js API routes response data hidden when accessing it through URL? I want to hide the routes because there is some data I don't want to be directly accessed by the user.
Probably quick & simple way to protect the API routes is through the stateless session management libraries like iron-session with save / creation and destroy endpoints to validate and invalidate the Next JS api routes
Try this github example by Vercel. This might a be good starting point.
Remember: Always use a best authentication mechanism to protect any direct api route call with appropriate privileges in place. DYOR
There is no way to hide API routes from users through url in nextjs. In fact, nextjs API routes are publically available to anyone when you host the website without exporting and hosting from out folder. I ended making server-side routes using node express and then connected to the frontend in nextjs.
It is extremely unworthy effort to hide API routes. and for protecting essential data in API..there is CORS and Authentication methods can prevent noicy unwanted traffic I found brilliant blog on this
https://dev.to/a7u/how-to-protect-nextjs-api-routes-from-other-browsers-3838
You can set an authorization header that checks auth key everytime user access that API, that way normal user wont be able to access the page without knowing the auth key
In Next.js version 13 you can use middleware to stuck the user from directly checking the route of your api by checking the req.referer then only your app can call and api of your app. Auth token can also be use inside middleware.
https://nextjs.org/blog/next-13-1#nextjs-advanced-middleware
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(req: NextRequest) {
const url = req.nextUrl
const { pathname } = url
if (pathname.startsWith(`/api/`)) {
if (!req.headers.get("referer")?.includes(process.env.APP_URL as string)) {
return NextResponse.json({ message: 'Unauthorized' }, { status: 401 });
}
}
return NextResponse.next()
}
export const config = {
matcher: ['/((?!_next|fonts|examples|svg|[\\w-]+\\.\\w+).*)'],
}
process.env.APP_URL is the url of your app for example : http://localhost:3000

How to correctly set redirect urls with Expo

I have an Expo application that is using AuthSession. I'm connecting my backend that does some stuff and afterwards should redirect to my app.
My issue is that this only works if I use the redirect url as exp://blablabla, which according to Expo's documentation, is wrong.
I should use something like https://auth.expo.io/#username/project-slug, but that just redirects to an empty page.
I have AuthSession set as
const url = Linking.makeUrl('/auth/success');
const result = await AuthSession.startAsync({
authUrl: `https://my-back-end-url/auth/login`,
returnUrl: url
});
The returnUrl doesn't seem to be doing anything, really.
Furthermore if I use the exp://blablabla url to redirect, it will only work to the root of my project, which I don't really want.
What am I doing wrong here?
Cheers!

Categories