I have a react app that I'm trying to add a Node/Express/MySQL backend to with OAuth. My React app is hosted on localhost:3000 and the express server is on localhost:4000. I added "proxy":"http://localhost:4000" to the react app's package.json file to send requests to the server. The Authorized Javascript Origin for the OAuth is http://localhost:4000. The Authorized redirect URI is http://localhost:4000/auth/google/redirect.
These are the errors I get in the browser's console when I try to get to the route on the server:
One says No 'Access-Control-Allow-Origin' header is present on the requested resource.
The other says 'Cross-Origin Read Blocking (CORB) blocked cross-origin response....with MIME type text/html.'
I have no clue what I'm doing wrong and I've been stuck since yesterday.
Failed to load https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fauth%2Fgoogle%2Fredirect&scope=profile&client_id={clientiddeletedbyme}.apps.googleusercontent.com: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://accounts.google.com/o/oauth2/v2/auth?response_type=code&redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fauth%2Fgoogle%2Fredirect&scope=profile&client_id={iddeletedbyme}apps.googleusercontent.com with MIME type text/html. See https://www.chromestatus.com/feature/5629709824032768 for more details.
Here is my code in the package.json file for my react app:
{
"name": "workout_tracker",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"firebase": "^5.3.0",
"jw-paginate": "^1.0.2",
"jw-react-pagination": "^1.0.7",
"normalize.css": "^8.0.0",
"random-id": "0.0.2",
"react": "^16.5.2",
"react-dom": "^16.5.2",
"react-headroom": "^2.2.2",
"react-icons-kit": "^1.1.6",
"react-redux": "^5.0.7",
"react-router-dom": "^4.3.1",
"react-scripts-cssmodules": "^1.1.10",
"react-swipe-to-delete-component": "^0.3.4",
"react-swipeout": "^1.1.1",
"redux": "^4.0.0",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"redux-devtools-extension": "^2.13.5"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"proxy":"http://localhost:4000"
}
Here is the code in my react app that sends the request to the server:
express=()=>{
axiosInstance.get("/google").then(res=>{
console.log(res);
}).catch(err=>console.log(err));
}
Here is the code in the server
let express = require("express");
let cors= require("cors");
let mysql = require("mysql");
const util = require("util");
const passportSetup = require("./config/passport-setup");
const passport = require("passport");
let app = express();
let connection =mysql.createConnection({
host: "localhost",
user: "root",
password: "root",
database: "Workout_Tracker",
socketPath: '/Applications/MAMP/tmp/mysql/mysql.sock'
});
app.use(cors(
{origin:"http://localhost:3000",
credentials:true,
allowHeaders:"Content-Type"
}
));
app.options("/google", cors());
app.get("/google", cors(), passport.authenticate("google",{
scope:['profile']
}));
...omitted a bunch of SQL queries
app.listen(4000, () => console.log("Listening on port 4000!"));
Here is the sample code of a new middleware you need to install to express BEFORE you define any routes:
const cors = require('cors');
app.use('*', function(req, res, next) {
//replace localhost:8080 to the ip address:port of your server
res.header("Access-Control-Allow-Origin", "http://localhost:8080");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials', true);
next();
});
//enable pre-flight
app.options('*', cors());
But before copy and pasting, just so you know that you need to npm install cors --save before importing the cors. The above sample code simply means:
we allow a different ip address to access the server for all the routes you defined
Allow a 'X-Requested-With' and a 'Content-Type' parameters inside the header. You normally don't have to specifically define these but its good to have them.
Only with the allow credentials set to true your session/cookies are able to store during front-end refreshing the pages, which I think might be helpful for your future development.
pre-flight request will also be allowed, which many Http libraries will send by default.
for your front-end, if you are using axios, you do need: axios.create({
withCredentials: true
}); to say: both react and express are agree to use CORS. And likewise in the other http libraries.
Here is some documentation you can have a look at:
https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Instead of using AJAX to request the endpoint, I should have navigated there through the browser. I used an <a> tag with an href of "http://localhost:4000" and it worked as expected.
Here's my sample use of CORS with expressJs, this is needed to be done on backend or server-side. Server stops access of it's API from outside world not client-side.
// IP's allowed all access this server
let whitelist = ['http://localhost:3000', 'http://127.0.0.1:3000'];
let corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true);
} else {
callback(new Error('Not allowed by CORS'));
}
}
};
// Cross-Origin Resource Sharing
app.use(cors(corsOptions));
Related
I am trying to deploy my first React.js app on Heroku. Everything seems to work fine link to app except the most important part - the Express.js REST API that I use to fetch data from my Postgres database and Stripe API is functioning normally on localhost, but when I deploy the app on Heroku, all the API routes I am trying to access return the same syntax error - Unexpected token < in JSON at position 0.
I understand that the issue is tied to how my app routes to the API. In other words, the fetch request is not able to get to the needed endpoint and thus return this syntax error, but I can't pinpoint exactly where is the issue - am I missing a '/' somewhere, have I incorrectly set up my environment variables, etc.?
Has someone had a similar issue or maybe someone can spot the issue in my code down below?
package.json
{
...
"private": true,
"main": "server.js",
"homepage": "https://dj-bbq.herokuapp.com",
"engines": {
"npm": "6.14.15",
"node": "14.18.1"
},
"dependencies": {
"#formspree/react": "^2.2.4",
"#stripe/react-stripe-js": "^1.7.0",
"#stripe/stripe-js": "^1.22.0",
"#testing-library/jest-dom": "^5.16.1",
"#testing-library/react": "^12.1.2",
"#testing-library/user-event": "^13.5.0",
"#userfront/react": "^0.2.22",
"cors": "^2.8.5",
"express": "^4.17.2",
"express-fileupload": "^1.2.1",
"helmet": "^5.0.1",
"jsonwebtoken": "^8.5.1",
"pg": "^8.7.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-router-dom": "^6.2.1",
"react-scripts": "4.0.3",
"stripe": "^8.195.0",
"web-vitals": "^2.1.2"
},
"devDependencies": {
"dotenv": "^10.0.0",
"nodemon": "^2.0.15",
"source-map-explorer": "^2.5.2"
},
"scripts": {
"start": "node server.js",
"heroku-postbuild": "npm install && npm run build",
"dev-start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"analyze": "source-map-explorer 'build/static/js/*.js'",
"server": "node server.js",
"nodemon": "nodemon server.js"
},...
server.js
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const path = require('path'); // Allows to access files through the server in our filesystem
const fileUpload = require('express-fileupload'); // Parses multipart/form-data requests, extracts the files if available, and make them available under req.files property.
/**
** ------------- GENERAL SETUP -------------
*/
// Provides access to variables from the .env file by using process.env.REACT_APP_variable_name
require('dotenv').config();
const nodeEnv = process.env.NODE_ENV !== 'production';
const devPort = process.env.REACT_APP_server_dev_port;
const prodPort = process.env.PORT // process.env.PORT
const devDomain = process.env.REACT_APP_dev_domain;
const prodDomain= process.env.REACT_APP_prod_domain;
const PORT = nodeEnv ? devPort : prodPort;
const domain = nodeEnv ? devDomain : prodDomain;
// CORS options
const corsOptions = {
origin: domain, // frontend_URL for heroku deployment
credentials: true ,
// Allows only the following HTTP requests to go through
methods: [
"PUT",
"POST",
"DELETE",
"GET",
],
"Access-Control-Allow-Headers": [
"Origin",
"X-Requested-With",
"Content-Type",
"Accept",
"Authorization",
],
};
//* Creates the Express server instance as "app"
const app = express();
//* MIDDLEWARE
// Called BETWEEN processing the Request and sending the Response in your application method.
app.use(helmet()); // Sets many http headers to make them more secure
app.use(cors(corsOptions)); // To allow cross origin conections (Allows our React app to make HTTP requests to Express application)
// Instead of using body-parser middleware, use the new Express implementation of the same thing
app.use(express.json()); // To recognize the incoming Request Object (req.body) as a JSON Object
app.use(express.urlencoded({ extended: true })); // To recognize the incoming Request Object as strings or arrays
app.use(fileUpload({
createParentPath: true
})); // Enables file uploading
//* HEROKU MIDDLEWARE
if (process.env.NODE_ENV !== 'production') {
// To load static files or client files from here http://localhost:3000/images/kitten.jpg
app.use(express.static(path.join(__dirname, 'public')));
} else if (process.env.NODE_ENV === 'production') {
// Serve static files - makes the build folder accessible to app.
app.use(express.static(path.joins(__dirname, 'build')));
// app.use(express.static(path.resolve(__dirname, 'build')));
}
/**
** -------------- SERVER ----------------
*/
// Determines the PORT and enables LISTENing for requests on the PORT (http://localhost:8000)
app.listen(PORT, () => {
console.debug(`Server is listening at http://localhost:${PORT}`);
});
/**
** ------- ROUTES / ENDPOINTS ---------
*/
// Go to /test to make sure the basic API functioning is working properly
app.get('/test', (req, res) => {
res.status(200).send('The Basic API endpoints are working.')
});
// Imports all of the routes from ./routes/index.js
app.use(require('./app-server/routes/allRoutes'));
// If req comes from one of these domains (origins), then allow the request with CORS.
app.use((req, res, next) => {
const corsWhitelist = [
domain,
];
if (corsWhitelist.indexOf(req.headers.origin) !== -1) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
}
next();
});
I have set-up a catch all route (router) for unkown routes in a different file
//* HEROKU - catch all for unrecognised routes
if (process.env.NODE_ENV === 'production') {
// Serve index.html file if it doesn't recognize the route
router.get('*', (req, res, next) => { // or * instead of /
res.sendFile(path.join(__dirname, 'build', 'index.html')); // resolve instead of join
})
}
And here is an example of a fetch request
const [recipes, setRecipes] = useState([]);
useEffect(() => {
let interval;
const fetchData = async () => {
try {
// const url = 'http://localhost:8000/recipes/display';
const url = `${customProxy}/recipes/display`;
const response = await fetch(url);
const json = await response.json();
setRecipes(json);
} catch(error) {
// console.error(error);
alert("Recipe displaying:" + error);
}
};
fetchData();
interval = setInterval(() => {
fetchData()
}, 86 * 1000)
return () => {
clearInterval(interval)
}
}, []); // Determine swhen to re-use useEffect, if this changes.
Thank you in advance for taking the time to consider the solution for issue!
Update 1
I started going through my project for the n-th time and previously I followed the guides found on Heroku to deploy my PERN app. The guides recommended using mars/create-react-app-buildpack to deploy the app, but after reading the documentation of this build pack it clearly says that this build pack is only meant for static react apps not react apps with its own custom node.js server.
In such cases, I am to use the mars/heroku-cra-node.
I have been following the documentation on how to set-up my folder structure, etc., but now, when I deploy the app, Heroku informs me of the following...
-----> Building on the Heroku-20 stack
-----> Using buildpacks:
1. https://github.com/mars/heroku-cra-node
-----> App not compatible with buildpack: https://github.com/mars/heroku-cra-node
bash: /tmp/codon/tmp/buildpacks/d07ae047a3685d9cfb39224105301a7dbdbfbe9c/bin/detect: No such file or directory
More info: https://devcenter.heroku.com/articles/buildpacks#detection-failure
! Push failed
I understand that the idea is that my folder structure is not as required by the build pack, but I am following its documentation by the letter.
Has anyone had any experience in using this build pack to deploy a PERN app to Heroku?
I noticed that this question of mine is still unanswered.
The issue, in the end, was that I was trying to use the Heroku free plan, but my app was too "big" for that so I either needed to split the back-end and front-end into two apps or to use a paid plan.
In the end, I actually changed my hosting service provider from Heroku to Digital Ocean. The app is still on their servers and works now - https://dj-bbq-i5gdc.ondigitalocean.app/ .
hello laravel i am trying to use socket.io with vuejs but i keep getting errors, i couldn't understand where i went wrong.
What I want to do is clearly when the form is submitted, it is listened to by the audience and instantly sees the post to the manager. Of course, this is not happening. I am using socket.io wrong. I couldn't understand.
laravel.local/:1 Access to XMLHttpRequest at 'http://localhost:3000/socket.io/?EIO=3&transport=polling&t=NNy_ruN' from origin 'http://laravel.local:8000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
server.js
var app = require('express')();
const server = require('http').createServer();
const io = require('socket.io')(server);
// http.listen(3000);
app.get('/', (req, res) => {
res.send('<h1>Hello world</h1>');
});
io.on('connection', socket => {
socket.on('new_appointment_create', function () {
console.log("okey");
io.emit('admin_appointment_list');
});
});
server.listen(3000, function () {
console.log('Listening on Port: 3000');
});
formpost.vue
import io from 'socket.io-client';
var socket = io('http://localhost:3000');
.then((response) => {
if (response.status) {
socket.emit('new_appointment_create');
this.completeForm = false;
}
})
adminlist.vue
import io from 'socket.io-client';
var socket = io('http://localh
created() {
this.getData();
socket.on('admin_appointment_list', () => {
console.log("list okey");
this.getData();
});
},
package.json
"devDependencies": {
"axios": "^0.19",
"bootstrap": "^4.0.0",
"cross-env": "^7.0",
"jquery": "^3.2",
"laravel-mix": "^5.0.1",
"lodash": "^4.17.19",
"popper.js": "^1.12",
"resolve-url-loader": "^3.1.2",
"sass": "^1.20.1",
"sass-loader": "^8.0.0",
"socket.io": "^3.0.3",
"socket.io-client": "^2.3.1",
"vue": "^2.5.17",
"vue-template-compiler": "^2.6.10"
},
"dependencies": {
"express": "^4.17.1",
"laravel-vue-pagination": "^2.3.1",
"v-mask": "^2.2.3",
"vue-resource": "^1.5.1"
}
The error you're receiving is due a feature from browsers called preflight that consists in the browser doing kind of "ping request" to the server that you want to access with an HTTP OPTIONS to get the response headers and check for the Access-Control-Allow-Origin header.
The idea is that your API should declare in this header which origins(domains) are allowed to consume your resources/APIs.
The "easiest" way to resolve this is to configure your API to respond with Access-Control-Allow-Origin: *.
But it's not the correct way, you shouldn't go to production * as configuration.
In my opinion the correct way to resolve this is use a http proxy while in dev, and in production you configure your Apache or NGINX or whatever http server you'll use to do so.
If you're using #vue/cli, it already has an option to configure a proxy server for development, take a look in the docs.
But fastforwarding the refactoring needed if you use the devProxy option, you will basically map an resource/context in the same server/port which is served you front-end to proxy requests/connections to your websocket.
Then you'll stop calling the http://localhost:3000 directly and will use the mapped resource/context.
For example:
In your vue.config.js
module.exports = {
devServer: {
proxy: {
'^/api': {
target: 'http://localhost:300',
ws: true
}
}
}
}
Then you will create the socket:
var socket = io(`${location.protocol}//${location.host}/api`);
Being honest with you, I've never used the devProxy with websockets, but the docs says it has support for it.
Server.js Code:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors')
const db = require('./DB/db');
const routes = require('./api/routes/routes');
const app = express();
const PORT = process.env.PORT || 3000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use(cors({
origin: '*'
}));
routes(app);
app.listen(PORT, () => {
console.log(`Server started at ${PORT}`);
});
package.json file:
{
"name": "LMS_Backend",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"joi": "^14.3.1",
"jsonwebtoken": "^8.5.1",
"mongoose": "^5.9.11",
"nodemailer": "^6.4.6"
}
}
Angular service file:
import { Injectable } from '#angular/core';
import { HttpClient, HttpParams, HttpHeaders } from '#angular/common/http';
const baseUrl = 'https://lmspreject-1.herokuapp.com/api/lms_project';
// const baseUrl = 'http://localhost:3000/api/lms_project';
#Injectable({
providedIn: 'root',
})
export class AdminServiceService {
constructor(private http: HttpClient) {}
register(adminDetails) {
console.log(adminDetails);
let headers = new HttpHeaders({
'Content-Type': 'application/json',
'Accept': 'application/json'
});
let options = {
headers: headers,
};
return this.http.post(`${baseUrl}/admin/register`, adminDetails, options);
}
}
Error:
Access to XMLHttpRequest at 'https://lmspreject-1.herokuapp.com/api/lms_project/admin/register' from origin 'http://localhost:4200' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Note: It works fine I run the app on the localhost but gives error on Heroku URL.
Regarding CORS, localhost behaves quite differently than remote origins, this can be very confusing.
I suspect that you didn't enable the CORS pre-flight OPTIONS endpoint. Your request is using a JOSN content type and therefore is not a "simple" cors request. It will be automatically preceded by an OPTION preflight request from the browser. Your server should be able to respond to that request.
See here how to enable it - https://www.npmjs.com/package/cors#enabling-cors-pre-flight
Do:
npm i --save cors
Add app.use(cors()) in server.js file.
Cross-Origin Resource Sharing (CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin.
You can do a CORS request from a HTTPS domain to another HTTPS domain. If you do http requests to call your https server, it is considered insecure an considered as force request to your server with tampered data.
Here,as I can see you are trying to access https server from your local http that's why you are getting an CORS issue.
I'm having trouble getting a little proxy working with my React app. I'm trying to use a little express server to keep some API keys secret so that my application can make use of a 3rd party API (the github API to be specific). I have a small express app running that I can query to get the API keys out of a .env file and attach those keys to my request to the 3rd party API.
Presently, I am able to start the front-end application and the express app simultaneously, and I can query the express app and get a response using my browser.
I'm trying to configure webpack to proxy my requests through this express app. In my webpack.config.js file I have:
//
devServer: {
port: 8080,
proxy: {
'/api/**': {
target: 'http://localhost:3000',
secure: false,
changeOrigin: true
}
}
}
//
Front-end application is running on port 8080, and my Express app is running on port 3000, both on the localhost.
In my React App, for trying to test whether this proxy is being detected/used, I have the following in a component:
//
handleSubmit(event) {
event.preventDefault();
fetch('/api/secret')
.then(res => {
console.log('RES: ', res)
res.json()
})
.then(data => {
console.log("Data: ", data)
return JSON.stringify(data)
})
this.props.onSubmit(this.state.username)
}
//
The backend code is super simple at the moment, but here it is:
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
require('dotenv').config();
// Initialize app
const app = express();
const port = 3000;
// Configure
app.use(bodyParser.json())
app.use(cors())
app.get('/secret', (req, res) => {
res.status(200)
res.send({ aSecret: process.env.<API_KEY> })
})
app.listen(port, () => console.log(`App is running on port ${port}`))
In my package.json I have the following (relevant script and dependencies):
...
...
"start": "concurrently --kill-others \"webpack-dev-server\" \"npm run server\"",
"server": "nodemon server/index.js"
},
"babel": {
"presets": [
"#babel/preset-env",
"#babel/preset-react"
]
},
"dependencies": {
"prop-types": "^15.7.2",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-icons": "^3.9.0"
},
"devDependencies": {
"#babel/core": "^7.8.7",
"#babel/preset-env": "^7.8.7",
"#babel/preset-react": "^7.8.3",
"babel-loader": "^8.0.6",
"body-parser": "^1.19.0",
"concurrently": "^5.1.0",
"cors": "^2.8.5",
"css-loader": "^3.4.2",
"dotenv": "^8.2.0",
"express": "^4.17.1",
"html-webpack-plugin": "^3.2.0",
"nodemon": "^2.0.2",
"style-loader": "^1.1.3",
"svg-inline-loader": "^0.8.2",
"webpack": "^4.42.0",
"webpack-cli": "^3.3.11",
"webpack-dev-server": "^3.10.3"
},
"proxy": "http://localhost:3000"
}
As you can see, in the component I'm (attempting to) making a request to api/secret and hoping to get back in the response the API key that I have stored in my .env.
When I query this route in my browser using fetch('http://localhost:3000/secret') I am able to access the API key successfully, so I know that when I run the npm run start script that both the React application and the Express application are starting up simultaneously.
When I click the button in my React component that sends a request to /api/secret I get the following output in the browser console (in keeping with the console logs I have in the react component at the moment):
I'm just not sure at this point what I'm doing wrong with the proxy configuration in the devServer webpack configuration.
I can see that the hostname is being automatically prepended to the /api/secret in the fetch within the React component.
Stated Goal: Webpack successfully detects the proxy server I'm using to server requests to the 3rd party (GitHub) API.
I apologize if this question is a repeat, I've spent several hours researching and fiddling with this configuration and have been unsuccessful in finding out how to configure this. This is my first attempt at spinning up a little proxy server as well. Thanks in advance for any help!
You need to return res.json()
handleSubmit(event) {
event.preventDefault();
fetch('/api/secret')
.then(res => {
console.log('RES: ', res)
return res.json()
})
.then(data => {
console.log("Data: ", data)
return JSON.stringify(data)
})
this.props.onSubmit(this.state.username)
}
My react app is up on localhost:3000 and node server is running on localhost:5000.
When I am trying to connect to the express API the route is going to 'localhost:3000/auth/google' instead of localhost:5000/auth/google
UserAction.js
export const updateLoginUser = (userData, scheme) => async dispatch => {
console.log(scheme);
if(scheme === 'google') {
// TODO: fetch user from the DB
const fetchedUser = await axios.post('/auth/google');
dispatch({
type: UPDATE_USER,
payload: fetchedUser.data
})
} else {
// TODO: fetch user from the DB
const fetchedUser = await axios.post('/api/get_user/', {
method: 'POST',
headers: {
'content-type': 'application/json'
},
body: JSON.stringify(userData)
})
dispatch({
type: UPDATE_USER,
payload: fetchedUser.data
})
}
}
setupProxy.js
const proxy = require('http-proxy-middleware')
module.exports = function(app) {
app.use(proxy('/auth/google', { target: 'http://localhost:5000' }))
}
NODE server.js
const express = require('express');
const mongoose = require('mongoose');
const keys = require('./config/keys');
const cookieSession = require('cookie-session');
const passport = require('passport');
const cors = require('cors');
const morgan = require('morgan');
require('./models/Users');
require('./services/passport'); // it is not returing anything hence no need of assigning
mongoose.connect(keys.mongoDBURI, { useNewUrlParser: true, useUnifiedTopology: true });
const app = express();
app.use(cors());
// Setup the cookie session
app.use(cookieSession({
maxAge: 30 * 24 * 60 * 1000, // Time till the cookie will be alive
keys: [keys.cookieKey]
}));
app.use(morgan('combined'));
// Make passport know to use the cookieSession
app.use(passport.initialize());
app.use(passport.session());
require('./routes/authRoutes')(app); // authRoute returing a function and we are immediatly invoking that function
const PORT = process.env.PORT || 5000;
app.listen(5000);
EDIT: react package.json
{
"name": "blogpost-frontend",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.19.0",
"http-proxy-middleware": "^0.20.0",
"node-sass": "^4.13.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-redux": "^7.1.3",
"react-router-dom": "^5.1.2",
"react-scripts": "3.2.0",
"redux": "^4.0.4",
"redux-thunk": "^2.3.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"proxy": "http://localhost:5000"
}
I am new to this hence I do not know how exactly proxy works.
you may need to rewrite your setupProxy.js as below
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
then do a npm install.
In my case that resolved the issue.
here you can see more details https://create-react-app.dev/docs/proxying-api-requests-in-development/
Also there it is mentioned as Note: This file only supports Node's JavaScript syntax. Be sure to only use supported language features (i.e. no support for Flow, ES Modules, etc).
The way to do it is to use what route you use in express at app.get('/what-here', ....) You use also in setupProxy.js at
function (app){ app.use('/what-here',
createproxyMiddleware({
target: URL,
change origin:true}).
The what-here is attached to the URL and the URL is proxied to the frontend URL that the client app uses. That is if the client is at localhost:3000 ant the server is at localhost:5000 the request is then at localhost:5000/what-here but it is shown as localhost:3000/what-here to the client. The mistake is to use different names at express then at setupProxy
I had the same problem. The problem is not the setupProxy.js, the problem is that the path to which axios is posting does not exist in the backend. This can be caused by a mispelling in the backend route.
Ensure the backend route path is the same as the frontend post path.
First ensure your setupProxy.js looks like this:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
and the axios.post starts with /api,mine was:
await axios.post("/api/conversion/convert", data);
I was posting using axios.post('/api/conversion/convert') but my express backend had a post route 'api/convertion/convert' which was a typo on my part (convertion instead of conversion) which made axios post to 3000 instead of 5000.
I don't know what kind of a bug is this, axios posting to 3000 instead of 5000 for mismatch in the backend route. The expected behavior is that it should post to 5000/wrong-post-path for easier debugging.
P.S Please upvote if this solves your problem. I am new to answering question and the upvote would really boost my account.
i think you forgot to add first part of app.listen(api, proxy()) and you have only proxy method, am problem may be that you didn't specified which url/path to go through proxy.
var express = require('express');
var proxy = require('http-proxy-middleware');
var app = express();
app.use(
'/api', // you miss this part in your server code
proxy({ target: 'http://www.example.org', changeOrigin: true })
);
app.listen(3000);
// http://localhost:3000/api/foo/bar -> http://www.example.org/api/foo/bar