I am trying to save this variable called server from the user. After they submit, they go to another page. On that page, I verify their server exists and if not send them back.
The session is saved when I run the post request because I immediately check via the get request if it exists (via client-side). However, if I refresh my page, the session is no longer defined and the user is sent back home (verified this with the logs). I think it is something cookie related, but I could not seem to get it to work.
Here is my sesssions.js route:
const session = require('express-session');
const express = require("express");
const router = express.Router();
router.use(session({
secret: 'ssshhhhh',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}));
router.get('/check', (req, res) => {
let sesh = req.session;
console.log("Checking server exists: " + sesh.server);
res.send(sesh.server);
});
router.post('/login', (req, res) => {
let sesh = req.session;
sesh.server = req.body.server;
console.log("Setting server: " + sesh.server);
res.send(sesh.server);
});
module.exports = router;
And this is how are the requests which both return promises:
function setSession(value) {
return $.post("/sessions/login", { 'server': value }).then();
}
function getSession() {
return $.get("/sessions/check").then();
}
Simple solution from a friend. You cannot instantiate middleware in a route. Just had to move the middleware instantiation to app.js.
Related
I'm coding a session with NodeJS, when I get the user connection first create a session.client with the MAC ADDRESS, so far so good, but then I ask to the client if he want to continue and login on the app with social -network like Facebook, Instagram, Tweeter or Google+, and then when the user is redirected to the social login it back with other session from passportjs and clear al my init data of session and I lost the client information. So, I tried to change the name of the data in session, session.data, session.test, session.whatever but always happen the same, when I test and the passport redirect me and back to my domain, the session is clean and it change with new data from passportjs, any one know what's happen here? any idea how to solve this?
the code run perfectly, the problem is the session when go and back to // the social login, it clear my init data and back with the passport data. // I need my init data to continue working!
this is just an extract of code. It works
'use sctrict'
const https = require('https'),
fs = require('fs'),
path = require('path'),
morgan = require('morgan'),
logger = require('express-logger'),
express = require('express'),
favicon = require('serve-favicon'),
bodyParser = require('body-parser'),
methodOverride = require('method-override'),
passport = require('passport'),
// config files
port = 443,
mongodbConfig = require('./config/mongodb-config'),
session = require('express-session'),
keys = require('./config/keys'),
options = {
key: fs.readFileSync('./config/ssl/server.key'),
cert: fs.readFileSync('./config/ssl/server.crt')
},
cookieParser = require('cookie-parser'),
loginAPRoutes = require('./routes/loginAPRoutes'),
passportSetup = require('./config/passport-setup'),
app = express()
// MongoDB - Mongoose connection
const mongoose = require('mongoose')
mongoose.Promise - global.Promise
mongoose.connect('mongodb://' + mongodbConfig.mongodb.route + '/' + mongodbConfig.mongodb.db, {})
.then(() => console.log('db connected'))
.catch(err => console.log(err))
// config
app.set('view engine', 'ejs')
// middlewares
app.use(morgan('dev'))
app.use(favicon(path.join(__dirname, 'public/img/', 'favicon.ico')))
app.use(bodyParser.urlencoded({
extended: false
}))
app.use(bodyParser.json())
app.use(methodOverride('X-HTTP-Method-Override'))
app.use(express.static(path.join(__dirname, 'public')))
app.use(session({
secret: 'cybor-cat',
resave: false,
saveUninitialized: true
}))
// initilize passport
app.use(passport.initialize())
app.use(passport.session())
// Main routes
app.use('/guest', loginAPRoutes)
app.use('/auth', loginAPRoutes)
// Run the server https
https.createServer(options, app).listen(port, () => {
console.log('NodeJS Server Started... splice.pro is running!')
})
router.get('/s/:site', (req, res) => {
data = req.query
data.site = req.params.site
req.session.data = data
console.log('===== session ========')
console.log(req.session)
console.log('====== session END =======')
res.render('login')
})
/////////////// GOOGLE AUTH ////////////////
// route for google login
router.get('/google', passport.authenticate('google', {
scope: ['profile', 'email']
}))
// route for google and redirect
router.get('/google/callback',
passport.authenticate('google'), (req, res) => {
if (!req.user) {
res.redirect('/guest/s/site')
} else {
/////////// here comes the new session from passport :( //////
////////// and lost the first data of my session /////
console.log(req.session.data)
//////////////// this show the session with info of user ///////
/////////////// but req.session.data is lost ///////////
res.redirect('/guest/startconnection')
}
}
)
/////////////// GOOGLE AUTH END ////////////////
Well, well, well.... I found my problem, my external site redirect me to my server with the ip and when the request of passport login redirect , it back to the domain name, that's why it generate a new session id ... A long day but at the end I found it !
I am using socket.io with express and using express session and express-socket.io-session, but I can't can't access properties of the express session in the socket.io session object and vice versa.
const server = require("http").createServer(app);
const client = require("socket.io").listen(server);
session = require("express-session")({
secret: "my-secret",
resave: true,
saveUninitialized: true
}),
sharedsession = require("express-socket.io-session");
app.use(session);
client.use(sharedsession(session, {
autoSave:true
}));
client.on("connection", (socket) => {
socket.on("input", data => {
console.log(socket.handshake.session.user)
socket.handshake.session.name = "bar"
socket.handshake.session.save()
})
})
app.post("/signup", (req, res, next) => {
req.session.user = "foo";
})
app.get("/test", (req, res, next) => {
console.log(req.session.name)
})
Both console.log() return undefined, as it seems like they both are two different objects.
I got my issue resolved, but can't seem to understand this weird issue when using var socket = io('http://localhost:8080') in the client HTML sock.io session id is differing from express session id, but when I do var socket = io() they both share the same session, and everything is working as expected.
i am new in node.js. i still couldn't figure out the meaning of configuration on session.
below is example of basic use of session
app.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
var session = require('express-session');
var cookieParser = require('cookie-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser('cookie'));
app.use(session({
cookie: {
domain: 'localhost',
signed: false,
maxAge:100000,
},
resave: false,
saveUninitialized:false,
secret:'cookie',
rolling:false,
unset:'keep'
}));
app.get('/', function (req, res) {
res.send('this is a router base page!');
});
app.get('/index1.html', function (req, res, next) {
res.sendFile(__dirname + '/index1.html');
next();
});
app.get('/index1.html', function (req, res) {
console.log(req.session.id);
});
app.post('/index1.html', function (req, res) {
if(!req.session.user) req.session.user = req.body;
res.setHeader('Content-Type','text/html');
res.write('session:' + JSON.stringify(req.session));
res.write('expires:'+ JSON.stringify(req.session.cookie.maxAge/1000));
res.end();
});
app.listen(1338);
when i refresh localhost:1338/index.htmlmany times, the req.session.id changes accordingly such as
CboUX1OOMa1veStAmf_9fsEd-ZwNYlW
kWkgsLXsDJcbtEIt9gfSWbg4_ScbG44p
jXLUt0fcCa-wH_jYsU64GznGj1ZNR44G
FjmjRHahDlaC79ngg7k2n1yWni6OHqpt
eLauXn3_SFNxmcWbHMZKAL4d0OVTwzqC
i don't get it why it changes every time even i haven't use post method.
if it changes according to every refreshing web page, what is the difference from req.session.regenerate
req.session.regenerate(function(err){
console.log(req.session.id);
});
but after i wrote username and password in front end form,and submit, then refresh web page again, it won't print session.id any more.
I think i may have some misunderstanding on concept of session.
can anyone help out?
It should give you same token if you introduce time duration setting in session configuration. Something like this
activeDuration: 5 * 60 * 1000
If you are interested for more detail please visit this link https://stormpath.com/blog/everything-you-ever-wanted-to-know-about-node-dot-js-sessions
There are many questions relating to getting a req.user undefined after social authentication, but I found none which could help me.
I have been able to successfully use the example for using passport for twitter authentication: https://github.com/passport/express-4.x-twitter-example. I tried to follow this pattern as closely as possible but cannot seem to get it to work.
Specifically, I am able to successfully authenticate, but the req.user is undefined. This makes no sense to me as my user data was returned no problem from the example.
I'm not inclined to believe this is a middleware problem (as it has been for others) as the middleware is the same as that used in the example. It could be something about having multiple domains, but I'm not sure what. All of this is being done on the localhost.
In Twitter, the app is set up so that
website is: 127.0.0.1:3000/signin
and the
callback url is: 127.0.0.1:2999/auth/twitter/return
As you can tell, my client is working on port 3000 and it is making calls to a server running on port 2999.
To briefly walk you through the code, the client on 127.0.0.1:3000/signin has a button which links to 127.0.0.1:2999/auth/twitter, thus initiating the authentication request. Under the hood, the express server is created in server/index.js--server. This imports the routes in routes/index.js, some of which the controller authenticate.js handles. As you can see, the oauth twitter request is made in authenticate.js. Again, authentication proceeds successfully, I am redirected to 127.0.0.1:3000/search. However, as you can see in this.twitter_callback, I am printing the req.user and it is undefined.
Please note that I have redacted the consumer key/secret from my code.
server/index.js
var cors = require('cors')
var bodyParser = require('body-parser')
var express = require('express');
var app = express();
var http = require('http').Server(app)
var io = require('socket.io')(http)
// NOT SURE WHY I NEED TO GO BACK 3 FOLDERS TO GET TO PORT_CONFIG
var port = require("../port_config.json").server_port;
var PORT = Number(process.env.PORT || port);
var routes = require('./routes/index.js')
var database = require('./database/db.js')
var db = new database()
app.use(cors()); // middleware that allows cross-platform requests
app.use(bodyParser.json());
db.dbConnect(function(err,db_instance){
// routes
routes(app, db_instance, io)
// send user polls on connection
// TEMPORARY (WILL BE GRABBED ON LOGIN)
var user = null // WILL BE SET AFTER LOGIN
io.on('connection', function(socket) {
var places_attending = db_instance.collection('places_attending')
places_attending.find({}).toArray(function(err,docs){
var places_user_attending = docs.map(doc => {
if (doc.attending.indexOf(user) !== -1) {
return {
id: doc.id,
name: doc.name,
num_attending: doc.attending.length
}
}
})
socket.emit('places_user_attending', places_user_attending);
})
})
})
http.listen(PORT, function () {
console.log('Backend server listening at http://localhost:' + PORT);
})
module.exports = http
routes/index.js
var Search = require('../controllers/search.js')
var Add = require('../controllers/add.js')
var Authenticate = require('../controllers/authenticate.js')
module.exports = function(app, db, io) {
var search = new Search(db, io)
var add = new Add(db, io)
var authenticate = new Authenticate(app)
app.route('/api/search')
.post(search.search_yelp)
app.route('/api/add')
.post(add.add_attendee)
app.route('/auth/twitter')
.get(authenticate.twitter_authentication)
app.route('/auth/twitter/return')
.get(authenticate.twitter_callback)
}
authenticate.js
function authenticate(app) {
var passport = require('passport');
var Strategy = require('passport-twitter').Strategy;
// Configure the Twitter strategy for use by Passport.
passport.use(new Strategy({
consumerKey: REDACTED,
consumerSecret: REDACTED,
callbackURL: 'http://127.0.0.1:2999/auth/twitter/return'
},
function(token, tokenSecret, profile, cb) {
// In this example, the user's Twitter profile is supplied as the user
// record. In a production-quality application, the Twitter profile should
// be associated with a user record in the application's database, which
// allows for account linking and authentication with other identity
// providers.
return cb(null, profile);
}));
// Configure Passport authenticated session persistence.
passport.serializeUser(function(user, cb) {
cb(null, user);
});
passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});
// Use application-level middleware for common functionality, including
// logging, parsing, and session handling.
app.use(require('morgan')('combined'));
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true }));
// Initialize Passport and restore authentication state, if any, from the
// session.
app.use(passport.initialize());
app.use(passport.session());
this.twitter_authentication = passport.authenticate('twitter')
this.twitter_callback = (
passport.authenticate('twitter', { failureRedirect: 'http://127.0.0.1:3000/signin' }),
function(req, res) {
console.log('REQ.USER OBJECT: ' + req.user)
res.redirect('http://127.0.0.1:3000/search');
}
)
}
module.exports = authenticate
Any help would be greatly, greatly appreciated.
The problem was in how my twitter_callback route was specified.
If I change the callback to this:
this.twitter_callback = app.get('/auth/twitter/return',
passport.authenticate('twitter', { failureRedirect: 'http://127.0.0.1:3000/signin' }),
function(req, res) {
console.log(req.user)
res.redirect('http://127.0.0.1:3000/search');
})
everything works fine. I think this has something to do with the middleware not being applied correctly the initial way I wrote it. Not exactly sure how I would rewrite it to export it, without using app.get in the twitter_callback though
This is my first time using Express' app.all(). When a user signs up through an outside oAuth provider, I still need them to provide an email after returning to the site. I'm basically setting them as inactive in the database and checking for req.session.active.
What I'm doing is
app.all('*', function(req, res, next) {
if(!req.session.active) {
if(req.path == '/complete_signup') {
next();
} else {
return res.redirect('/complete_signup');
}
}
});
But this doesn't seem to be working. How can I correctly check if the user is already redirected?
If you can suggest a method other than app.all(), that would work, too.
EDIT:
On second look, this is working, but none of the external resources (stylesheets, javascripts, etc.) seem to be loading since they don't match req.path.
You can use the express-redirect-loop middleware (which uses sessions since HTTP Referrer header is unreliable). This will only work for requests that support cookie storage/jar (e.g. browser).
const express = require('express');
const session = require('express-session');
const redirectLoop = require('express-redirect-loop');
const app = express();
app.use(
session({
secret: 'test',
resave: false,
saveUninitialized: true
})
);
app.use(redirectLoop());
app.get('/', (req, res) => res.sendStatus(200));
app.get('/bar', (req, res) => res.redirect('/foo'));
app.get('/foo', (req, res) => res.redirect('/foo'));
app.get('/baz', (req, res) => res.redirect('/bar'));
app.listen(3000);