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

newman
  • 6,841
  • 21
  • 79
  • 126
  • Are you using the `create-react-app`? – Matt Carlotta Oct 30 '18 at 01:45
  • yes, it started that way. – newman Oct 30 '18 at 01:51
  • If you're using the CRA v2, then they changed the way the `proxy` works: https://stackoverflow.com/a/52846108/7376526 – Matt Carlotta Oct 30 '18 at 01:53
  • 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? – newman Oct 30 '18 at 02:14
  • Can you share your server index.js? – SakoBu Oct 30 '18 at 03:51
  • @SakoBu pls see my updates. – newman Oct 30 '18 at 03:58
  • @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. – newman Oct 30 '18 at 04:11
  • 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) – Matt Carlotta Oct 30 '18 at 07:15
  • @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. – newman Oct 30 '18 at 16:16
  • 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: https://i.imgur.com/cPIked9.png – Matt Carlotta Oct 30 '18 at 16:42
  • @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? – newman Oct 30 '18 at 16:55
  • 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. – Matt Carlotta Oct 30 '18 at 16:59
  • @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! – newman Oct 30 '18 at 17:12
  • No problem. Glad you figured it out. – Matt Carlotta Oct 30 '18 at 17:39

0 Answers0