Can't get redis session in sailsjs - node.js

I have two APIs. When i hit first API from Atom, i am setting a parameter in session which is successful. But when i hit second API and trying to get session by req.session, it creates a new session instead of giving previous session. Ho do get session and parameter i set in first API into second API.
Below is my first API code in which i am setting session parameter.
function firstAPI(req, res) {////This is POST API
session = req.session;
////Doing something with req
session.message="my message";
sails.log.info("session " + JSON.stringify(session));
res.send(""session is set);
}
In terminal i am getting following session
session {"cookie":{"originalMaxAge":180000,"expires":"2017-02-28T05:03:25.304Z","httpOnly":true,"path":"/"},"message":"my message"}
Below is my second API code in which i am trying to retrieve session.
function secondAPI(req, res) {
sails.log.info("session= " + JSON.stringify(req.session));
}
Log for second API is
session= {"cookie":{"originalMaxAge":180000,"expires":"2017-02-28T05:04:18.623Z","httpOnly":true,"path":"/"}}
Following is my config/session.js file
module.exports.session = {
secret: '123abc',
cookie: {
maxAge: 3 * 60 * 1000,
},
adapter: 'redis',
host: 'localhost',
port: 6379,
db: 0,
prefix: 'sess:',
}
You can see i have set cookie time 3 mins. and in between i hit the second API. Anyone find any mistake in this?

Second request must send the cookie set by first request (in Cookie header) in order to retrieve the session.
Browsers as a client sends cookie set for the domain, by default. Other clients like cURL need to be specified. If you specifically want to use Atom check whether/how it supports to send cookie.
See Cookies & sessions:
Sessions are server-side files that contain user information, while Cookies are client-side files that contain user information. Sessions have a unique identifier that maps them to specific users. This identifier can be passed in the URL or saved into a session cookie.
Most modern sites use the second approach, saving the identifier in a Cookie instead of passing it in a URL (which poses a security risk). You are probably using this approach without knowing it

Related

Express session, how do I get the session after posting? I see the session ID in browser under cookies, but it's undefined in request object?

Sorry guys, I'm really new to sessions and cookies and I'm trying to understand the mechanism behind it. I wanted to add register/login to my simple website and in order to do I need to understand web authentication and I really think I will have tons of questions regarding this topic.
Initially, I have register page that sends info after clicking submit button to a node server using express.
I'm trying to see what happens, so I've created a session in post route, it's created in the browser (connect.sid), then I commented out the part that creates that session and just tries to redisplay the session object, but it's undefined, but I still can see the session in the browser's cookies section, so what's going on? Thanks
app.use(session({
secret:"my test secret",
cookie:{},
resave:false,
saveUninitialized:false
}))
app.post("/register", (req, res) => {
req.session.usertest = "testsession_hardcodedvaluefornow";
console.log(req.session.usertest); // -> this is okay when above line to create is uncommented
//but when I comment the session assignment, it becomes undefined?
res.send("In register...");
})
I can see the session cookie even after commenting out the create session and posting over and over.
connect.sid s%3A_TahsTv0xhY-iHIdjDRblYJ_aZZ5oiSd.do7JcOGR1FaXPcFFIQ6hg5AW%2B0XVsYwIRO8vndyjDzs
req.session.id produces a different value (not undefined) even if I delete my session in the browser, so not sure where that comes from.
There is no "usertest" key in the session object, therefore it is undefined. The reason it's not undefined when you uncomment that line is because you create that key yourself in that instant with that line.
You can get the whole session object by using req.session, the session id by using req.session.id and the session cookie by using req.session.cookie.
Edit
To further clarify: a session will be made for every connected client. That is why you can see the cookie in the browser. That has no meaning however, it's just a way to uniquely identify that client (without actually telling you who that client is). Any information about that session (whether they're logged in, user id,...) needs to be stored in a session store. Express-session will use memory store by default, if the server restarts all that information will be lost, which is why that key doesn't exist. In order to preserve that information it has to be stored in a persistent session store. More information on session store implementations for express-session and how to use them can be found here: https://www.npmjs.com/package/express-session
As for the cookie values you get, those are the default ones set by express-session since you haven't set any yourself. You can change the maxAge to let it expire (or set it so 10 years or more for a more persistent session), you can specify a domain to which that cookie belongs, you can set it to secure (to only allow it over secure connections, e.g. https) and httpOpnly is by default true. httpOnly cookies cannot be accessed/altered by the client (although you can see them in the browser), do not set this to false.

One database per user security

I develop an app with Ionic where each user got its own PouchDB database synchronise with its own remote CouchDB database. I use couch_peruser=true so any user that want to access its database need to authenticate.
This system is easy to do if we store the username & password locally or if we ask the user to give them anytime a sync is needed but none of these options are good (security concern or non user-friendly).
I came with those two options, but none is working:
1) The best option that came to me was to use Cookie Authentication, just save the token locally and use it, but unfortunately to connect with the token couchdb ask to use the header :
Cookie: AuthSession={TOKEN}
But this is not possible because it is a non-authorized header (unsafe) and is rejected by the browser.
2) Second option is to use couchdb Proxy Authentication but it is the same as saving the username and password as the token is valid forever.
Is there any way other way of handling authentication ? I was thinking to use an alternative users database, generate a fake password & username then send this credential to be saved into the user app. In this case if the security is compromise the user can change its password so the server can change the second password too (in the same way we revoke a token), but then there is still a problem because with the stolen credential it is always possible to access directly to the couchdb database without being seen..
Thanks for your help, i was not able to use couchdb-auth-proxy so I ended up with the following solution that has the advantage to prevent direct access to couchdb :
1) Create a node server to authenticate the user, if auth successful then return couchdb token to the app for cookie authentication
2) Create a node server used only as a couchdb proxy using node-http-proxy
with the following code :
(it is required that this router code come very early in the express middleware otherwise it might change the response and pouchdb sync does not work, so place it before app.use(bodyParser.json())
)
router.all('/*', (req: Request, res: Response, next: NextFunction) {
let token = req.get('X-Auth-Cdb-Token');
let httpProxy = require('http-proxy');
const proxy = httpProxy.createProxyServer({
target: target,
});
req.headers['Cookie'] = 'AuthSession='+token
proxy.web(req, res);
});
3) In your app set the pouchdb remote database with the following header :
remoteDB = new PouchDB(url, {
skip_setup: true,
ajax: {
headers: {
'X-Auth-Cdb-Token': couchdbToken
},
withCredentials: false
}
})
If you write a Progressive Web App, the Cookie Authentication is great for this, because the browser handles it for you. Use the pouchdb-authentication to log in directly to CouchDB.
On the CouchDB side, configure the Cookies as persistent, and put some longer lifetime on it. You can set it to 2 weeks, for example, so your users will only be asked for the password if they haven't logged in for two weeks.
The cookie TTL is automatically refreshed once a certain threshold is reached (I recall it's at half of the cookie TTL, so it would be refreshed if the cookie is more than a week old).
CouchDB is built for the web, so you can take advantage of it. ;-)

Session variables not being set in expressjs

I've tried many ways of setting the session variables but have been unsuccessful in finding a solution. The problem more precisely is that the session (custome) variables are not being passed to other routes (so they aren't being stored in the default MemoryStore presumably).
All of the code is available at https://github.com/codexa/pictroid/blob/session/app.js
This is the portion of code for assigning the session variable (https://github.com/codexa/pictroid/blob/session/app.js#L304-311)
console.log(req.session);
req.session.regenerate(function(){
// Store the user's primary key
// in the session store to be retrieved,
// or in this case the entire user object
req.session.user = "some user";
req.session.auth = true;
});
I'm aware of the fact that this is async and the proceeding code will be executed while this does but making it synchronous doesn't solve the problem.
As an example, I'm trying to retrieve the custom "req.session.user" in the root dir route (https://github.com/codexa/pictroid/blob/session/app.js#L87-L88)
app.get('/', function(req, res) {
console.log(req.session.auth);
...
So can anyone please tell me what I'm doing wrong and how to solve it?
Thanks in advance.
You should not set secure: true if you are using http because cookies with secure: true will only be sent for https requests. If you want to keep secure: true, you will need to start an https server instead. If you are doing this only for development purposes, then you can just temporarily remove secure: true until you put your code into production (where you use https).
Also on an unrelated note, you can avoid regenerate() and the session fixation problem by only starting a session after a successful authentication and for authenticated routes. This will also help decrease the number of sessions in your session store from visitors who never sign in or crawlers (unless of course you need to store session data for unauthenticated users).

Setting cookies in Express.js XHR response object from node_redis callback

I'm having trouble getting a cookie to be passed back with an Express.js response. The situation is that I'm making an XHR containing user credentials, checking if the user exists, if the user does exist and credentials are correct I store the users info in Redis via node_redis. In the callback that I hand Redis I create a cookie on the response object, then send the customer object to the browser.
Here is the Redis code (note: I'm not using Express sessions so I just added the Redis client into req.session via middleware):
req.session.hmset('user', customer, function(err, status) {
res.cookie('sid', 'sessionID', {
maxAge: 3600000,
path: '/',
httpOnly: false
});
res.send(customer);
});
The odd thing is that when I add a console.log(res._headers); right after creating the cookie, there is a 'set-cookie' header present, but it never makes it to the browser. Might I have bad request headers? Something else? I'm completely stumped here...

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