title: Express, Create-React-App, & passport-twitter
body: <p>I am setting up Twitter oauth on my <code>create-react-app</code> application by using a helper function (via <code>axios</code>) on the front end to initiate the <code>passport</code> oauth process on my backend. I am currently in development, so I am hosting my express server on port <code>3001</code> and my front end on port <code>3000</code> with a proxy on the front end to port <code>3001.</code> I have set up CORS permissions via the <code>cors</code> npm package.</p>
  
  <p>No matter what set of configurations I try, I am unable to complete the Twitter OAuth process. I have tried switching ports, keeping the same ports; I have tried proxying my backend with <code>express-http-proxy</code>.</p>
  
  <p>I have used <code>http://127.0.0.1</code> instead of <code>localhost</code> in both my callback function and my initial api call, trying both ports <code>3000</code> and <code>3001</code>.</p>
  
  <p>I'm at the point where I'm not sure where I'm going wrong or if I need to abandon the <code>passport-twitter</code> for other solutions. </p>
  
  <p>In every case, I keep getting the following error:</p>
  
  <pre><code>Failed to load https://api.twitter.com/oauth/authenticate?
  oauth_token=alphanumericcoderedactedherebyme: No 'Access-Control-Allow-Origin' 
  header is present on the requested resource. Origin 'http://localhost:3000' is 
  therefore not allowed access.
  </code></pre>
  
  <p>Depending on the configuration I have attempted, I get origin as <code>null</code> or <code>http://localhost:3001</code> or <code>http://127.0.0.1</code>.</p>
  
  <p>Note, I successfully call my backend api numerous times for other reasons, such as connecting to <code>Yelp Fusion API</code>. Moreover, I am using middleware to log my session data and I can see that I am successfully getting <code>oauth_token</code> and <code>oauth_token_secret</code> from Twitter. The call is failing on the next leg of the oauth process:</p>
  
  <pre><code>[0] *************SESSION MIDDLEWARE***************
  [0] Session {
  [0]   cookie:
  [0]    { path: '/',
  [0]      _expires: 2018-01-06T20:20:31.913Z,
  [0]      originalMaxAge: 2678400000,
  [0]      httpOnly: true },
  [0]   'oauth:twitter':
  [0]    { oauth_token: 'alphanumericcoderedactedherebyme',
  [0]      oauth_token_secret: 'alphanumericcoderedactedherebyme' } }
  [0]
  [0] Logged In:
  [0] __________ false
  [0] **********************************************
  </code></pre>
  
  <p>Here is relevant portions of my code -</p>
  
  <p><strong>BACKEND CODE</strong></p>
  
  <p>SERVER.JS</p>
  
  <pre><code>// Dependencies
  
  const express = require("express");
  const cors = require("cors");
  const passport = require('passport');
  
  // Initialize Express Server
  const app = express();
  
  // Specify the port.
  var port = process.env.PORT || 3001;
  app.set('port', port);
  
  app.use(passport.initialize());
  app.use(passport.session());
  
  //enable CORS
  app.use(cors());
  
  //set up passport for user authentication
  const passportConfig = require('./config/passport');
  
  require("./controllers/auth-controller.js")(app);
  
  // Listen on port 3000 or assigned port
  const server = app.listen(app.get('port'), function() {
      console.log(`App running on ${app.get('port')}`);
  });
  </code></pre>
  
  <p>PASSPORT.JS</p>
  
  <pre><code>const passport = require('passport');
  const TwitterStrategy = require('passport-twitter').Strategy;
  
  passport.use(new TwitterStrategy({
      consumerKey: process.env.TWITTER_CONSUMER_KEY,
      consumerSecret: process.env.TWITTER_CONSUMER_SECRET,
      callbackURL: process.env.NODE_ENV === 'production' ? process.env.TWITTER_CALLBACK_URL : 'http://localhost:3000/auth/twitter/callback'
      },
      function(accessToken, refreshToken, profile, done) {
          ...etc, etc, etc
  </code></pre>
  
  <p>AUTH-CONTROLLER.JS</p>
  
  <pre><code>const router = require('express').Router();
  const passport = require('passport');
  
  module.exports = function(app) {
      router.get('/twitter', passport.authenticate('twitter'));
  
      router.get('/twitter/callback',
          passport.authenticate('twitter', {
              successRedirect: '/auth/twittersuccess',
              failureRedirect: '/auth/twitterfail'
          })
      );
  
      router.get('/twittersuccess', function(req, res) {
          // Successful authentication
          res.json({ user: req.user, isAuth: true });
      })
  
      router.get('/twitterfail', function(req, res) {
          res.statusCode = 503;
          res.json({ err: 'Unable to Validate User Credentials' })
      })
  
      app.use('/auth', router);
  }
  </code></pre>
  
  <p><strong>FRONTEND CODE</strong></p>
  
  <p>HELPERS.JS</p>
  
  <pre><code>import axios from 'axios';
  
  export function authUser() {
      return new Promise((resolve, reject) =&gt; {
          axios.get('/auth/twitter', {
              proxy: {
                  host: '127.0.0.1',
                  port: 3001
              }
          }).then(response =&gt; {
              resolve(response.data);
          }).catch(err =&gt; {
              console.error({ twitterAuthErr: err })
              if (err) reject(err);
              else reject({ title: 'Error', message: 'Service Unavailable - Please try again later.' });
          });
      });
  }
  </code></pre>
  
  <p><hr>
  <hr>
  <strong>UPDATE</strong>
  I verified that Passport Authentication works on my backend port. I called the endpoint directly in the browser and was redirected to the Twitter auth which then returned to my callback the new user saved in my schema which was saved to the session data.</p>
  
  <p>This means the problem lies with the use of Create-React-App on a different port than my backend.</p>
  
  <p><code>http://127.0.0.1:3001/auth/twittersuccess</code></p>
  
  <pre><code>"user": {
      "_id": "redactedbyme",
      "name": "Wesley L Handy",
      "__v": 0,
      "twitterId": "redactedbyme",
      "favorites": [],
      "friends": []
  },
  "isAuth": true
  </code></pre>