Why is my react router not passing my express route to server?
Asked Answered
M

0

0

I tried to add social login to my (already working) react/express app, and I got it working in localhost. However, when I deploy it to production, the social login doesn't work. This is how it gets started

<a href="/api/auth/google">Google+</a>

However, in production, it stays at https://sample.com/api/auth/google in my browser. So, it appears the react router is catching it first before express. How?

In localhost, it works because the proxy in package.js

"proxy": {
    "/api": {
      "target": "http://localhost:4000",
      "ws": true
    }

Now, how can I do this for production?

By the way, all my server APIs starts with '/api/...'. Also, in my react routes, I don't have a catch-all component.

UPDATE: Here is my server.js

var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var flash = require('connect-flash');
var cookieParser = require('cookie-parser');
var path = require('path');
var fs = require('fs');

var app = express();
var isSecured = true;
app.isDevMode = app.get('env') == 'development'

require('./server/config/log')(app)

var port = (process.env.PORT || app.isDevMode) ? 4000 : (isSecured ? 443 : 80);
app.set('port', port);

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json({ limit: '10mb' }));

app.use(flash()); // use connect-flash for flash messages stored in session

var server = require('http').createServer(app);
if (!app.isDevMode && isSecured) {
  var options = {
    ca: fs.readFileSync('ca_bundle.crt'),
    key: fs.readFileSync('private.key'),
    cert: fs.readFileSync('certificate.crt')
  }
  server = require('https').createServer(options, app);
}

db.on('error', console.error.bind(console, 'connection error:'));

db.once('open', function () {
  console.log('Connected to MongoDB');

  var routes = require('./server/routes');
  routes.init(app);

  if (app.isDevMode) {
    app.use(express.static(__dirname));
  }
  else {
    app.use(express.static(path.join(__dirname, 'client/build')));

    app.get('/*', function (req, res) {
      res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
    });

    if (isSecured) {
      require('http').createServer(function (req, res) {
        res.writeHead(307, { "Location": "https://" + req.headers['host'] + req.url });
        res.end();
      }).listen(80);
    }
  }
  server.listen(app.get('port'), function () {
    console.log('Server listening on port ' + app.get('port'));
  });
});

module.exports = app;

Here is my routes:

app.get('/api/auth/google', passport.authenticate('google', { scope: ['https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/userinfo.email'] }))
app.get('/api/callback/google', passport.authenticate('google', {successRedirect: '/?action=login&provider=google', failureRedirect: '/?action=login'}))

UPDATE: Here is the morgan log. I added a number for each line for my reference. Line 4 started when I click the link to send '/api/auth/google', and finished at line 6.

1. GET /api/get/list?parm={%22kind%22:%22Prod%22,%22limit%22:5,%22createdOn%22:-1} 304 - - 22.959 ms
2. GET /images/logo.png 200 3432 - 17.410 ms
3. GET /service-worker.js 200 3097 - 3.398 ms
4. GET /static/js/main.cef8cdac.js 304 - - 5.180 ms
5. GET /images/two.png 304 - - 4.908 ms
6. GET /service-worker.js 200 3097 - 3.838 ms

So, basically, the request didn't come to express server. Actually, if I had a catch all route in react, I can see it's hitting there.

Here is the network log:

enter image description here

Merrillmerrily answered 30/10, 2018 at 1:40 Comment(14)
Are you using the create-react-app?Rois
yes, it started that way.Merrillmerrily
If you're using the CRA v2, then they changed the way the proxy works: https://mcmap.net/q/1021185/-deploying-create-react-app-to-heroku-with-express-backend-returns-invalid-host-header-in-browserRois
Before i try that...is it right that proxy is for dev (localhost) only, right? As I said, my localhost works without problem. So, will that help my case?Merrillmerrily
Can you share your server index.js?Foolish
@Foolish pls see my updates.Merrillmerrily
@matt your link doesn't work for me. In fact I'm not sure if that accepted answer is working at all because setupProxy.js is not used anywhere.Merrillmerrily
You might be using CRA v1. Do me a favor, go back to what you had before, and install npm i -S morgan to your API dependencies. Then include it where you're defining your express middlewares: app.use(morgan('tiny')). Now you should see requests being logged to your console when you make any requests to the API. First make sure everything works in development, then try in production. This will tell you exactly where the issue is -- bad request (possibly proxy related) or incorrect backend routing (this assumes you can monitor the production server via a terminal)Rois
@matt Thank you very much for follow up. I attached a few lines of the log above. So, basically, the express is not seeing the request.Merrillmerrily
Next step is to determine WHERE the request is going. Go into your browser developer tools and look at the Network tab and make sure the subtab XHR or All is selected (either one). Then trigger your request and it should show up in the tab. Hover over the request to see its destination URL (ex: http://example.com/api/google). For example: i.imgur.com/cPIked9.pngRois
@matt ok, I uploaded the screenshot for all network log after I click the button. Strange, I don't see anything related there. Is the ServiceWorker making trouble?Merrillmerrily
I had trouble with the ServiceWorker when I first started building my website (which is why I removed it). It has also been known to mess with production assets. Ummm, you can try commenting it out, rebuild your app, clear your browser cache and cookies and try again. It may or may not help, but worth a try.Rois
@matt hey, you know what? It is the service worker! Once I remove it (and unregister it in browser), it starts working. Oh god, this was a nightmare and made me struggle for days. Thank you very much!Merrillmerrily
No problem. Glad you figured it out.Rois

© 2022 - 2024 — McMap. All rights reserved.