Authenticate by Token, then by Session if Token fails, using Passport?

I am working on adapting an existing web application with a NodeJS + Express backend, to a PhoneGap / Steroids app. Currently authentication for the webapp is handled by Passport (http://passportjs.org/) using sessions.

app.use( passport.initialize() );
app.use( passport.session() );

Works great in a browser. Unfortunately it seems that session cookies do not work in PhoneGap. So requests sent to the server just get rejected.

The recommended solution for PhoneGap is to use a token strategy instead, where a unique token is included with every request to the server, as in an api end-point.

So, here is what I am wondering:

Is it possible to adapt passport.session() so that if no session cookies are found, it will instead check for a req.token and authorize against that?

I note that there are already some token-based strategies for Passport available. (eg https://www.npmjs.org/package/passport-http-bearer) However all of these strategies seem to assume that sessions will not be used, and are turned off. What I really need is to use both, so if one authentication fails (eg session), it can pass over and check against another authentication (token).

Has anyone implemented something along the lines of this? Any suggestions / pointers would be appreciated.

This is almost exactly the same use case that lead us to write a JSON Web Token session middleware module. If you're using Redis it should fit nicely into your stack.

https://www.npmjs.org/package/jwt-redis-session

If you change the requestKey initialization parameter to something like "jwtSession" instead of "session" you can run this middleware alongside your existing cookie based session middleware. Then in your routes you can check for req.session.whatever or req.jwtSession.whatever and handle higher level functionality independent of the cookie/JWT transport mechanism.

You might have to modify your passport strategy and/or serialize/deserialize functions, but it shouldn't be too much work to merge this middleware into an existing passport based application.

Regardless of whether or not you want to use that module I think you should consider using something based on JSON Web Tokens. When a user authenticates your server would send their token back to the phonegap app which would then send the token in each subsequent request. Here the JWT would simply replace the functionality browsers support via cookies. It can be a bit tricky to manage session expirations via JWT's since the expiration is baked into the claims so it's impossible to "refresh" a session's TTL without regenerating a new token. This is what lead us to fall back to redis to manage expirations.

Either way what you're looking for is not a randomly generated UUID, but an encrypted token, such as a JWT, that contains just enough session identification data to replace the functionality of cookies.