Node.js. Authentication library with token functionality.

I have a working knowledge of the passport for node , but it does not have such things as:

  • creating a persistence token (for example, in authlogic / session / session.rb # L35
  • perishable tokens for password reset
  • remember me functionality
  • managing these properties to enter / exit the system in the model class, etc.

Are there any libraries that solved this in the Node.js community? If there is something as reliable (or along the way to being as reliable) as Devise for Rails , that would be fine, but anything that solves this problem a token problem will also work.

The crazy thing is a lot of examples that store the user id in the session!

 request.session['userId'] = user.get('id') 

It just asks for a hack.

It should be something like this:

 require.session['persistenceToken'] = App.User.generateRandomToken() 
+6
source share
3 answers

The one-time password strategy (the so-called one-time token) for resetting the password is what I will implement. Given Passport's architecture, this can easily be a standalone module, and it wouldn't surprise me to know that someone else has already implemented such a thing.

Remember that persistence token functionality is also what I would like to support. Preferably, I would like it to be a separate strategy, but this may require some basic support. If this turns out to be the case, a few extra lines in req.logIn ( https://github.com/jaredhanson/passport/blob/master/lib/passport/http/request.js#L28 ) should be able to cover it.

Regarding the storage of the user ID in the session, I do not see much risk, given that by default in Connect / Express the properties of the session are completely stored in the backend and are viewed by the unique sid that is set in the encrypted cookie. An attacker must have both a unique sid secret and a session in order to spoof requests.

Mozilla uses Passport as part of its identification effort to link the browser with other providers that lack BrowserID support (see browserid-bigtent ). Given their requirements, developers can be sure that Passport meets stringent security requirements.

(Ultimately, serialization of the session in the Passport is the responsibility of the application, therefore, if necessary, a random token can be used instead of the user ID if necessary. Obviously, this should be done if the data is stored directly in a cookie, but I would assume that this is the worst approach .)

As for managing these properties on the model, Passport is designed to completely modify the model / ORM. I do not intend to ever change this fact, since I think that these solutions are best left to the application (and Passport is more flexible as a result of delegation of this responsibility). Nevertheless, I think that it is possible for other modules to build themselves on top of the Passport in order to provide this functionality.

All that said, I think Passport is the most reliable Node.js auth solution available. Your first three queries would go a long way to make it more, and should be easy to complete. I would like to collaborate in getting these features, so feel free to contact me.

Finally, in case anyone is interested, first-class API authentication is now at work, in the authinfo branch. Based on this, passport-http-oauth implements OAuth server strategies that can be combined with oauthorize middlware as tools for building OAuth servers. This is not completely baked, but it will be another effective Passport feature when it is ready.

+8
source

At the same time, the following should be sufficient: Adjust as necessary to fit your application and the desired cookie duration. Checking the username and password is a kind of crappy way to detect login attempts, but it works pretty well with the passport.

 app.use(function(req, res, next) { if( typeof(req.body.username) !== "undefined" && typeof(req.body.password) !== "undefined" ) { if(req.body.remember == 1) { req.session.cookie.maxAge = 365*24*60*60*1000; } else { req.session.cookie.maxAge = 24*60*60*1000; } } next(); }); 
+2
source

Although I would definitely like to see these functions in the passport.js file, they are not installed yet.

I created a simple random token generator for use with the passport.js serilizeUser () function, and the modified Justen answered a bit to suit my needs. In fact, the only difference is that if the โ€œrememberโ€ option is not set, the session will last as long as the browser is open.

This is my serializer with a random access token generator. I use Mongodb and Mongoose, but the implementation should translate well to other systems.

Basically, I get the time and add a random 16-character string to it. Then, in the serializeUser () function, I check that no other user has the same token (the token must be unique!).

 User.methods.generateRandomToken = function () { var user = this, chars = "_!abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", token = new Date().getTime() + '_'; for ( var x = 0; x < 16; x++ ) { var i = Math.floor( Math.random() * 62 ); token += chars.charAt( i ); } return token; }; 

Here's the serializer:

 passport.serializeUser( function ( user, done ) { var createAccessToken = function () { var token = user.generateRandomToken(); app.User.findOne( { accessToken: token }, function (err, existingUser) { if (err) return done( err ); if (existingUser) createAccessToken(); // Run the function again - the token has to be unique! else { user.set( 'accessToken', token ); user.save( function ( err ) { if (err) return done( err ); return done( null, user.get('accessToken') ); }) } }); }; if ( user._id ) { createAccessToken(); } }); 

... and here is my middleware version that handles the โ€œremember meโ€ functionality. I would prefer it to be somehow part of the serializeUser or core.sys function. However,

 app.use( express.session( { secret: 'secret_key' } ) ); app.use( function (req, res, next) { if ( req.method == 'POST' && req.url == '/login' ) { if ( req.body.remember ) { req.session.cookie.maxAge = 30*24*60*60*1000; // Rememeber 'me' for 30 days } else { req.session.cookie.expires = false; } } next(); }); app.use( passport.initialize() ); app.use( passport.session() ); 

I hope this helps. It took me a couple of hours to figure this out, and I'm not quite sure if this is the best way to do this, but now it works for me.

+2
source

Source: https://habr.com/ru/post/919003/


All Articles