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
Related
I'm trying to sett a session-id cookie on my client react application. Somehow this does not work and all I get is the standart io session cookie in the browser.
On the other hand it works with a static served HTML file which builds up a socket.io connection.
Here is my server-side code:
var app = require("express")();
var server = require('http').Server(app);
var io = require('socket.io')(server);
let expressSession = require('express-session');
let sharedsession = require("express-socket.io-session");
var path = require('path');
var host = 'process.env.HOST' || '0.0.0.0';
var port = process.env.PORT || 4000;
server.listen(port, host, function () {
console.log("Server running on: " + host + " : " + port);
});
if (process.env.NODE_ENV === 'production') {
//Set static folder
app.use(require('express').static('client/build'));
}
let session = expressSession({
secret: 'my-secret',
//store: new redisStore({ host: 'localhost', port: 6379, client: redis, ttl: 260}),
resave: true,
saveUninitialized: true,
cookie: {
maxAge: 10000,
httpOnly: true,
sameSite: true,
secure: true,
},
})
app.use(function(req, res, next) {
res.header('Content-Type', 'application/json;charset=UTF-8')
res.header('Access-Control-Allow-Credentials', true)
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
)
next()
})
app.use(session);
io.use(sharedsession(session, {
autoSave: true
}));
io.on('connection', function (socket) {
console.log(`socket with id ${socket.id} connection established`);
socket.handshake.session.userdata = Math.random();
socket.handshake.session.save();
console.log(socket.handshake.sessionID);
client:
let socket = io(serverIP, { autoConnect: false });
useEffect(() => {
socket.on("connect", () => {
console.log("Connected");
});
socket.open();
}, []);
on a simple HTML file like this the session cookie gets set:
<script src="/socket.io/socket.io.js"></script>
<script type="text/javascript">
socket = io();
Both cases are over HTTP. The socket connection also gets established with both variants and the io cookie gets set. And the react App is built and being served from the build folder.
What could I be missing? Thanks for any advice!
EDIT FROM 02.03.2019:
As it turns out the error might come from a missing request or something. When I use a local socket.io.js directly added to the HTML everything works fine. If I use socket.io-client directly imported in my react app or a external CDN it wont work. Seems like it only works after there has been I request to a local ressource. Anyone knows what could be the diference between those two approaches and what could be the reason for this behaviour?
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:
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.
I'm making an ionic app for android and today I implemented a server side nodejs (express) Restful API with mongodb on cloud9.
But when I trigger a http request to the url, I keep getting the error mentioned in the title:
This is my angular http request on ionic (simply to test first):
app.controller('DashCtrl', function($scope, $http, $q) {
$http.get('https://[workspace]-[user].c9users.io/api/capture')
.then(function(result) {
console.log(result);
});
});
This is an image of my workspace:
I used the following code to make the database:
api.js
var Capture = require('../models/capture');
module.exports = function(router) {
router.get('/capture', function(req, res){
var capture = new Capture();
// capture.birdname = req.body.birdname;
// capture.place.city = req.place.body.city;
// capture.place.country = req.place.body.country;
capture.birdname = "Pigeon";
capture.save(function(err, data){
if(err)
throw err;
res.json(data);
});
});
router.get('/captures', function(req, res){
Customer.find({}, function(err, data){
res.json(data);
})
})
}
capture.js
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var captureSchema = mongoose.Schema({
birdname: String,
place: {
city: String,
country: String
}
});
module.exports = mongoose.model('Capture', captureSchema)
database.js
module.exports = {
'url': 'mongodb://' + process.env.IP
}
server.js
var express = require('express');
var app = express();
var mongoose = require('mongoose');
var configDB = require('./server/config/database.js');
mongoose.connect(configDB.url);
var api = express.Router();
require('./server/routes/api')(api);
app.use('/api', api);
app.listen(process.env.PORT, process.env.IP);
console.log('Listening on port ' + process.env.PORT)
Anyone have an idea why I'm getting this error and what I need to do to fix this?
I'm guessing it has something to do with the server allowing me to send requests to the API though I don't know how to implement that.
Is there also a way to secure my database (API key maybe) and how would I implement this?
Thanks in advance
I am using MEAN.JS and I want to store some parameter for each user during his session (from the opening of the website until the closing of the browser without login), and I want this parameter to be accessible from the client side by AngularJS and from the server side in the ExpressJS route handlers.
Please forgive my poor English
Use an express session and set up routes for angular to query:
var express = require('express'),
logger = require('morgan'),
bodyParser = require('body-parser'),
cookieParser = require('cookie-parser'),
expressSession = require('express-session');
var app = express();
app.use(logger("tiny"));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser('yousecretcode'));
app.use(expressSession({secret: 'yourothersecretcode', saveUninitialized: true, resave: true}));
var router = express.Router();
router.get('/session/set/:value', function(req, res) {
req.session.mySession = req.params.value;
res.send('session write success');
});
app.get('/session/get/', function(req, res) {
if(req.session.mySession)
res.send('the session value is: ' + req.session.mySession);
else
res.send("no session value");
});
app.use('/', router);
var server = app.listen(8097, function() {
console.log('BASIC SESSION server is listening on port %d', server.address().port);
});
Reference: http://blog.arisetyo.com/?p=492
There is an express module called redis that offers a more advanced solution as the aforementioned reference highlights. Refer to meanjs documentation if you require reference to query the routes or use the Yeoman generator(recommended).
I hope this helps you.