Node.js everyauth cluster error - node.js

I write scalable application with node.js and have a problem.
When I click on facebook auth link (/auth/facebook) and when it's redirect me back — throws the error:
{"error":{"message":"redirect_uri isn't an absolute URI. Check RFC 3986.","type":"OAuthException","code":191}}
I think, it's because I use cluster. I try to set RedisStore for session:
RedisStore = require('connect-redis')(express);
...somecode...
app.use(express.session({ store: new RedisStore(), secret: 'secret code'}));
But it's still not work. Also, the "findOrCreateUser" function work correct and i get user info as I want. All I need is redirect user to index page.
I'm use Express 3, Node 0.8.14
Everyauth have the same issue on github https://github.com/bnoguchi/everyauth/issues/153
Thanks in advance!

I'm resolved my problem by using passportjs instead everyauth.

Related

Getting a request timeout on Heroku with passportJS

I've been struggling with this all night but I haven't found an answer. I created an application which uses Passport JS for authentication. The users are saved in a MongoDB database, works perfectly on my local machine.
For that reason, I attempted to upload the app on Heroku. I added the mlab add-on and imported the data from my local database. When I visit the mlab dashboard the data is there.
The problem is that when I fill the form and hit enter, the app doesn't do anything and the in the console of the web browser the following error appears: "Failed to load resource: the server responded with a status of 503 (Service Unavailable)". I don't know what it's wrong and I need to fix it.
Among all the things I've read I think that a possible error could be that I'm not using things like connect-redis or connect-mongo (don't know which is best) with express-session. This is my code (middlewares):
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.use(cookieParser())
app.use(session({
name: 'session',
secret: '53kre7',
resave: false,
saveUninitialized: true
}))
app.use(passport.initialize())
app.use(passport.session())
So I really hope you can help me because I want to learn how to do it right. Thank you so much
My mistake. Heroku named the variable as MONGODB_URI while in my code I had MONGOLAB_URI. So I wasn't pointing to a real database. Problem solved.

Node+Passport.js + Sessions + multiple servers

Passport is great. I now discovered that I have some problem with how it handles sessions.
I must be using it wrong.
All works well for me with login + sessions + user data I store in my database.
However I find that when I move to production environment (cloud on EC2 with multiple servers), I lose the login session each time.
This is now clear to me - probably happens since the session is unique to each server.
So my question is - how do I get around this..
I guess I will need to store my own cookie on the user's browser?
Does this mean that I cannot use express.session at all?
Thanks,
Ilan
OK,
So basically what I was looking for (not sure it would be the same answer for everyone else) was a way to store session data between loadbalanced instances without making a DB call for every page view, which seems excessive to me, since I just need to keep the user signed in to Google/FB.
It seems that the answer I was looking for was the cookie-session middleware
https://github.com/expressjs/cookie-session
This needs to replace the default express.session mechanism which uses MemoryStore. BTW MemoryStore itself gives you a warning when run that it will not scale past a single process, and also that it may cause a memory leak.
Which if I understand correctly is serializing the session data itself into the session cookie (encrypted) instead of just using a session ID in the session cookie.
This seems perfect to me. Obviously I don't expect it to work if you have a lot of session data, since a cookie is limited in size. In my case, I just needed the name, ID and avatar url, so I think this will suffice.
Thanks for everyone who helped.
You need to store your session data in a 'global' area, that is accessible to all your servers. This could be redis or another DB.
Take the example from MEAN.JS. Here they use express-session with a MongoDB storage container (since they are a MEAN stack ; ), via connect-mongo. Their project is super easy to set up, if just for an example.
Code while setting up express is like this:
//top of file
var session = require( 'express-session' )
mongoStore = require( 'connect-mongo' )( {
session: session
} );
//...later in setup
// Express MongoDB session storage
app.use( session( {
saveUninitialized: true,
resave: true,
secret: config.sessionSecret,
store: new mongoStore( {
db: db.connection.db,
collection: config.sessionCollection
} )
} ) );
// use passport session
app.use( passport.initialize() );
app.use( passport.session() );

Connect-mongo Alternative for Express 4

I am looking to implement cookiestore in my Express app, I followed this question
Best Session Storage Middleware for Express + MongoDB
and
https://github.com/kcbanner/connect-mongo
for my Express 3.x project, but for Express 4, connect middleware is deprecated.
Which is the suitable alternative for connect-mongo?
Middleware has been extracted out of the core and moved individual modules. This changes how you set up the app but you have the option to use the same middleware as before. The overview explaining how to migrate from 3.x to 4.x lists the modules that can be used as replacements for the Connect middleware.
The syntax will be slightly different as you explicitly install the modules, such as express-session, and the app.use statements are modified to reflect this. The options you pass to these modules, however, are the same as it was with the Connect middleware...so you can pass your connect-mongo details to express-session and keep rolling along.
So you don't have to change unless there's another problem that isn't clear in your original question...and there could be other problems if you have a large, established app. But if you are following a tutorial, you should be early enough in the process that this won't be a major issue.
Edit: It looks like there's also been discussion about Express 4 on the connect-mongo github page. There are more examples there about how to use this module with the new version of Express...
Edit 2: The code, referenced a few times on the github page, looks like this:
var session = require('express-session');
var MongoStore = require('connect-mongo')(session);
app.use(session({
secret: 'youshouldputyourownsecrethere',
store: new MongoStore({
db : mongoose.connection.db,
})
}));

user authentication using socket.io

I've red this tutorial: http://howtonode.org/socket-io-auth.
It shows how to authenticate users using express and socket.io.
But is there a way to authenticate users using only socket.io without the need for express?
edit:
For session handling I use RedisStore (https://github.com/LearnBoost/Socket.IO/wiki/Configuring-Socket.IO).
Whats left is a module to create authentication cookies.
Does anyone know of a socket.io implementation I can use to create an authentication cookie like you can do with session handling?
I know this is bit old, but for future readers in addition to the approach of parsing cookie and retrieving the session from the storage (eg. passport.socketio ) you might also consider a token based approach.
In this example I use JSON Web Tokens which are pretty standard. You have to give to the client page the token, in this example imagine an authentication endpoint that returns JWT:
var jwt = require('jsonwebtoken');
// other requires
app.post('/login', function (req, res) {
// TODO: validate the actual user user
var profile = {
first_name: 'John',
last_name: 'Doe',
email: 'john#doe.com',
id: 123
};
// we are sending the profile in the token
var token = jwt.sign(profile, jwtSecret, { expiresInMinutes: 60*5 });
res.json({token: token});
});
Now, your socket.io server can be configured as follows:
var socketioJwt = require('socketio-jwt');
var sio = socketIo.listen(server);
sio.set('authorization', socketioJwt.authorize({
secret: jwtSecret,
handshake: true
}));
sio.sockets
.on('connection', function (socket) {
console.log(socket.handshake.decoded_token.email, 'has joined');
//socket.on('event');
});
The socket.io-jwt middleware expects the token in a query string, so from the client you only have to attach it when connecting:
var socket = io.connect('', {
query: 'token=' + token
});
I wrote a more detailed explanation about this method and cookies here.
Instead or wiring up authentication and session handling code manually, I'd recommend to go with a dedicated module, such as session.socket.io (but please note that this is a module that requires Express as well).
I guess (but don't know) that there were downvotes because you need some sort of session handling, and you most probably do not want to do this manually as well ;-). Hence it's a quite good idea to stick with Express here.
Nevertheless, it's an interesting question, although I can not answer on how to do it without Express.
I am quite new to node.js, just started a few days ago. and i only can answer to the first part to the question, which is user authentication without the use of express. and i also got no session-style handling yet.
the reason I am still answering to this question is to help out other people who are new to node with a more simple alternative solution for the beginning.
the solution i am currently using in my learning project (a socket.io - based chat, what else?) is using the http server for authentication.
if you can't get a valid authentication on the http server, you'll never get access to the page with the socket.io interface.
the user authentication on the http server is handled by reading out some POST data. only if the POST data is valid user data the user is allowed to move on to the chat where the socket.io interface is.

Mashery IODocs - Can it support passportjs authentication from my REST API?

I am using iodocs from Mashery to be the developer front end to my REST API. My API is written with Node / Express, and uses PassportJS to authenticate the user (local strategy). My implementation requires the user to use the /login endpoint, passing in username and password. Then, Passport serializes the user in a cookie, so that subsequent requests do not need to log in.
When using iodocs, the cookie that Passport sets ("connect.sid") is not passed back in subsequent requests.
Is there a way to do this? Is there an authentication method that IODocs supports that works this way?
Cookies WILL traverse across the ports. An issue you may be encountering is that "connect.sid" is also being set by I/O Docs in that it's using the Express session.js middleware module, so that cookie value is probably getting overwritten.
Try updating I/O Docs app.js with a different cookie name in the session initializer -- setting the "key" value:
app.use(express.session({
secret: config.sessionSecret,
key: 'iodocs.connect.sid',
store: new RedisStore({
'host': config.redis.host,
'port': config.redis.port,
'pass': config.redis.password,
'maxAge': 1209600000
})
}));

Resources