Why is my react router not passing my express route to server? - reactjs

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
Google+
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:

Related

Angular 4 Node Mssql

I am a newbie when it comes to web development . I am currently working to get a real time web project up and running . I have a ms sql server 2014 working in my workplace and have installed node.js/ and used express generator to generate out an application . I have used mssql node module to connect and retrieve data from mssql server and it works.Although, Things that are confusing to me at this point:
how do i add angular 4 into the equation to help with the frontend development?i have already done npm install --save anular/cli but do not know where to start regarding creating input forms with drop downs whose values are to retrived from the DB .
my app.js:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var index = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', index);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
my index.js (i tried to create a connection with myssql and display a table in the index.html jade file)
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
GetData(function(recordset)
{
res.render('index', {projects: recordset })
});
});
function GetData(callback )
{
var sql = require ('mssql');
const config = {
user: 'sa',
password: 'password',
server: 'localhost\\SQLEXPRESS',
database: 'xxxxx',
options: {
encrypt: false // Use this if you're on Windows Azure
}
};
var connection = new sql.Connection(config, function(err)
{
var request = new sql.Request(connection);
request.query('select * from Project_Type' , function(err, recordset)
{
callback(recordset);
});
});
}
module.exports = router;
Some more questions:
Is this the right place to start a sql connection ? or should i put in in the app.js file
and other advice as to how to setup the environment and angular to properly speak with the db would be highly appreciated.

socket.io is not consistently connecting

I've just added socket.io to my MEAN stack app. It's not consistent in its connections. This is what I get when I fire up the server and connect through a browser:
GET /socket.io/?EIO=3&transport=polling&t=LTnYzIi 200 1.948 ms - 3956
POST /socket.io/?EIO=3&transport=polling&t=LTnYzJL 404 1.617 ms - 66
GET /socket.io/?EIO=3&transport=polling&t=LTnYzrU 200 1.612 ms - 3956
POST /socket.io/?EIO=3&transport=polling&t=LTnYzs6 404 1.974 ms - 66
GET /socket.io/?EIO=3&transport=polling&t=LTnY-jT 200 1.652 ms - 3956
POST /socket.io/?EIO=3&transport=polling&t=LTnY-kE 404 0.975 ms - 66
However, if I stop the server and restart it the moment the browser makes the request (in the background), the client connects and it works fine. It really has to connect everytime there's a communication right?Please tell me what I'm missing.
Here's my package.json socket.io call:
"socket.io": "^1.4.6"
My app.js looks like this:
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var expressValidator = require('express-validator')
var mongodb = require('mongodb');
var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/newphase1");
var async = require('async');
var config = require('./config.js');
var routes = require('./routes/index');
var api = require('./routes/api');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(favicon(__dirname + '/public/favicon(4).png'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '/public')));
app.use(expressValidator({
errorFormatter: function(param, msg, value){
var namespace = param.split('.'),
root = namespace.shift(),
formParam = root;
while(namespace.length){
formParam += '[' + namespace.shift() + ']';
}
return {
param: formParam,
msg:msg,
value:value
};
}
}));
var api = require('./routes/api')(app,express,io);
app.use('/api', api);
app.get('*',function(req,res){
res.sendFile(__dirname + '/public/views/index.html');
});
io.on('connection', function(socket) {
console.log('client connected!');
});
http.listen(config.port,"127.0.0.1",function(err){
if(err){
console.log(err);
}else{
console.log('listening on port 3000');
}
})
My socket.io script file (from CDN) in my index.js(angular):
<script src="https://cdn.socket.io/socket.io-1.4.6.js"></script>
My service for socket.io:
.factory('socketio',function($rootScope){
var socket = io.connect("http://localhost:3000");
return {
on: function(eventName,callback){
socket.on(eventName,function(){
var args = arguments;
$rootScope.$apply(function(){
callback.apply(socket,args);
});
});
},
emit: function(eventName,data,callback){
socket.emit(eventName,data,function(){
var args = arguments;
$rootScope.apply(function(){
if(callback){
callback.apply(socket,args);
}
});
});
}
}
});
It does get connected, but not consistently. Any ideas?
For some reason
npm start
gave me the above inconsistency while
node app.js
works fine.

Catch all routes loading blank page Angular NodeJs

I was working on Angular app with routing (NodeJs as backend). Routing through pages works fine but when I try to reload page it gives 'cannot load path /home'. I browsed through and got to few solutions like THIS.
My code is
app.get('*', function (req, res) {
res.sendFile('mypath/index.html');
});
But this loads up blank page. Is there any way I can solve this issue?
This us how my server.js looks like
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var port = process.env.PORT || 8080; // set our port
var staticdir = process.env.NODE_ENV === 'production' ? 'dist.prod' : 'dist.dev'; // get static files dir
// get all data/stuff of the body (POST) parameters
app.use(bodyParser.json()); // parse application/json
//app.use(bodyParser.json({ type: 'application/vnd.api+json' })); // parse application/vnd.api+json as json
//app.use(bodyParser.urlencoded({ extended: true })); // parse application/x-www-form-urlencoded
app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
app.use(express.static(__dirname + '/' + staticdir)); // set the static files location /public/img will be /img for users
// routes ==================================================
app.set('views', __dirname + '/app');
app.set('view engine', 'html');
require('./devServer/routes')(app); // configure our routes
// start app ===============================================
app.listen(port); // startup our app at http://localhost:8080
console.log('Starting sever on port ' + port); // shoutout to the user
exports = module.exports = app; // expose app
app.get('/', function (req, res) {
res.render('index', {
page: 'index'
}
});
then out this into your config,
app.set('views', 'directory where index.html is');

Express-session not persistent

im currently trying to save data in express sessions.
Im using the following packages:
"connect-mongo": "^0.8.2"
"express": "~4.0.0"
"express-session": "^1.11.3"
"mongoose": "~3.6.13"
I'm implementing the sessions this way:
// Loading packages
var express = require('express');
var app = express();
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
// Connect to MongoDB
var mongoose = require('mongoose');
var options = { server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
replset: { socketOptions: { keepAlive: 1, connectTimeoutMS : 30000 } } };
mongoose.connect(process.env.DATABASE, options);
var router = express.Router();
// Session storage
router.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
store: new MongoStore({mongooseConnection: mongoose.connection}),
cookie: {
maxAge: 60*60*24*7*1000
}
}));
// Routes
router.route('/user/me')
.get(function(req, res) {
console.log(req.session);
});
router.route('/auth/login')
.post(function(req, res) {
req.session.userId = req.params.id;
});
app.use('/api', router);
var port = process.env.PORT || 8080;
app.listen(port);
console.log('Magic happens on port ' + port);
Now i have the following problem:
When i try posting to /api/auth/login using a software called "Postman REST Client" (Chrome extension) it works, and the user id will be logged when getting /api/user/me.
But if i try posting to /api/auth/login in an angular.js app, it does not save the session values. I always get a clean session object without the userId.
Also there are no cookies saved.
Could you please help me?
Greetings: Max

Angular + Node.js HTTP & HTTPS (SSL)

I want to use https for the post requests in my payment view. I stumbled over diff tutorials and now my setup is the following (and I still don't get it running):
Certificates
I generated certificates for my development environment using this tutorial:
http://greengeckodesign.com/blog/2013/06/15/creating-an-ssl-certificate-for-node-dot-js/
Node.js
I followed answer #2 to setup the http and https server in node:
Listen on HTTP and HTTPS for a single express app
It looks like that:
environment = require('./config/config.js')()
express = require('express')
bodyParser = require('body-parser')
app = express()
portHTTP = process.env.PORT || 61361
portHTTPS = 3030
mongoose = require('mongoose')
morgan = require('morgan')
http = require('http')
https = require('https')
socket = require('socket.io')
#SSL Server
fs = require('fs')
sslOptions = {
key: fs.readFileSync(__dirname + '/config/ssl/server.key'),
cert: fs.readFileSync(__dirname + '/config/ssl/server.crt'),
ca: fs.readFileSync(__dirname + '/config/ssl/ca.crt'),
requestCert: true,
rejectUnauthorized: false
}
#Database
configDB = require('./config/database.js')(environment)
mongoose.connect(configDB.url,{auth:{authdb:configDB.authdb}}, (err)->
if (err)
console.log(err)
)
db = mongoose.connection
db.on('error', console.error.bind(console, 'connection error:'))
db.once('open', () ->
console.log "Database established"
)
#Express Application
app.use(morgan('dev'))# log every request to the console
app.use(bodyParser.urlencoded({ extended: true }))
app.use(bodyParser.json())
rootPath = __dirname + '/../../'
app.use('/bower_components', express.static(rootPath + 'bower_components'))
app.use('/partials', express.static(__dirname + '/../partials'))
# Routes
require('./node/routes.js')(app, db) # load our routes and pass in our app and fully configured passport
# Launch the application
https.createServer(sslOptions,app).listen(portHTTPS, () ->
console.log("Secure Express server listening on port #{portHTTPS}")
)
http.createServer(app).listen(portHTTP)
io = socket.listen(https)
#app.listen(portHTTP)
console.log('Unsecure Express server listening on port #{portHTTP} environment: #{environment}')
Angularjs
I installed the angular module:
https://github.com/btford/angular-socket-io
And added it to my index.coffee
angular.module "app", [lots of dependencies, 'btford.socket-io', 'myCodeService']
.config ($stateProvider, $urlRouterProvider) ->
...states...
.factory('mySocket', (socketFactory) ->
return socketFactory({
ioSocket: io.connect('https://localhost:3030/',{secure: true})
#ioSocket: io.connect('https://cdn.socket.io/socket.io-1.3.4.js',{secure: true})
})
)
I added the two script tags into my index.html
<script src="../bower_components/angular-socket-io/socket.js"></script>
<script src="http://localhost:3030/socket.io/socket.io.js"></script>
Gulp Setup
And I serve in gulp with nodemon and browsersync
gulp.task('serve',['watch'], function(cb){
var called = false;
return nodemon({
script: paths.tmp + '/serve/server.js',
watch: [paths.src + '/node', paths.src + '/config'],
ext: 'coffee',
tasks: ['templateCache', 'partials_tmp'],
env: { 'NODE_ENV': 'development' } ,
nodeArgs: ['--debug=9999']
})
....
function browserSyncInit(files, browser) {
browser = browser === undefined ? 'default' : browser;
browserSync.instance = browserSync.init(files, {
startPath: '/#/',
browser: browser,
proxy: "http://localhost:61361"
});
}
I get an empty response from socket.io and I don't see anything in my browser which bugs me to accept the certificate.
There is an https option for browsersync but I don't really know how to split the traffic/ or if this is done automatically in node.js.
io = socket.listen(https) is incorrect. You should be passing the server instance, not the https module:
// ...
var srv = https.createServer(sslOptions,app);
srv.listen(portHTTPS, () ->
console.log("Secure Express server listening on port #{portHTTPS}")
)
io = socket.listen(srv);
// ...
Also your <script> src that points to socket.io.js should be https and not http.
To split the routing in the front end this can be used:
.run ($rootScope, $window, authUserService) ->
#Listens for state changes and redirects User if he is not logged in
$rootScope.$on "$stateChangeStart", (event, toState, toParams, fromState, fromParams) ->
#After login send user to share
if toState.name is "payment" and !authUserService.isSecure()
event.preventDefault()
$window.location.href='https://localhost:3030/#/spenden'
true

Resources