-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Access req object inside serializeUser and deserializeUser functions #111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I'll give my standard reply. This is more related to authorization rather than authentication. My recommendation is to set this up as additional middleware, something like:
That work for you? |
My first instinct with the issue I am having was also to have access to the request object, but based on all the other issues of people wanting the request object inside With the node-orm2 library, it can be configured to work via express middleware: app.use(orm.express("mysql://username:password@host/database", {
define: function (db, models) {
models.person = db.define("person", { ... });
}
}));
app.listen(80);
app.get("/", function (req, res) {
// req.models is a reference to models used above in define()
req.models.person.find(...);
}); You can see here that once the database is connected and the route is hit, you have access to the models on the request object. When incorporating this into passport configuration: passport.use({ passReqToCallback: true }, new LocalStrategy(function (request, username, password, done) {
request.models.User
.find({ username: username })
.limit(1)
.run(function (err, users) {
var user = users[0];
if (err) {
done(err);
} else if (!hasher.verify(password, user.password)) {
done(null, false);
} else {
done(null, user);
}
});
}));
passport.serializeUser(function (user, done) {
done(null, user.id);
});
passport.deserializeUser(function (id, done) {
// don't have access to request object here
}); I don't have access to the request object, which has the model I need to connect to the database to deserialize the user. Suggestions? |
I would make Models a global object defined by a required instead of trying Models is a static library for returning DB objects, correct? Sent from my iJimmy On Apr 13, 2013, at 12:32 PM, Eli Perelman notifications@github.com wrote: My first instinct with the issue I am having was also to have access to the With the node-orm2 https://github.com/dresende/node-orm2 library, it can var express = require('express');var orm = require('orm');var app = express(); You can see here that once the database is connected and the route is hit, passport.use({ passReqToCallback: true }, new LocalStrategy(function
passport.serializeUser(function (user, done) { I don't have access to the request object, which has the model I need to — |
The node-orm2 library automatically adds the models to every request as part of its middleware implementation. I am sure I could expose them once out of one of the initial requests: var User;
passport.use({ passReqToCallback: true }, new LocalStrategy(function (request, username, password, done) {
if (!User) {
User = request.models.User;
}
User
.find({ username: username })
.limit(1)
.run(function (err, users) {
var user = users[0];
if (err) {
done(err);
} else if (!hasher.verify(password, user.password)) {
done(null, false);
} else {
done(null, user);
}
});
}));
passport.deserializeUser(function (id, done) {
User.get(id, done);
}); but this seems a little hackish. Thoughts? |
@eliperelman, I'm struggling with the same thing. Were you able to come up with anything better? I've only come up with something similar to what you're doing above or keeping a separate db connection with the models redefined on it. |
I just want to share my solution for anybody struggling with this issue. Please note, that this will only work as described with the new node-orm2 version that supports a third argument app.use(orm.express('...', {
define: function (db, models, next) {}
}); File stack.js require defineModels = require('./model').define;
app.use(orm.express('sqlite://sqlite3.s3dbt', { define: defineModels })); File model.js var async = require('async'),
definedModels;
module.exports.define = function (db, models, next) {
definedModels = models;
var curriedLoad = function (file) { return function (cb) { db.load(file, cb); }; };
async.waterfall([
curriedLoad('.model/user'),
curriedLoad('.model/posting'),
// ...
], function (err) {
db.models.user.hasMany(db.models.posting);
db.sync(next);
});
};
module.exports.model = function (name) {
return definedModels[name];
} You can now use the following in your passport's var User = require('./model').model('user');
var deserializeUser = function (id, callback) {
User.get(id, callback);
}; |
We are having a similar issue to this original problem, access to req object within deserializeUser. This issue seems to have gotten off-topic and is now mostly related to using the node-orm2 library. We need access to the request object within deserializeUser because we use a REST service to deserialize the user instead of a database and the REST service needs information from the request in order to know what domain name the user requested, etc... I was just about to fork the project for this but then found this issue, please let me know if there is a work around that you can think of, otherwise I'll just fork and submit a PR. |
Addressed by merging #160. |
Fantastic news! Thanks @jaredhanson! |
I need to enforce that a user is only logged in at one location at a time per device type (we allow them to log in on one computer, one tablet, and one phone); simplest way to do that seems to be to just store the last session id for each type on my user object and then in deserialize I return null if the session id isn't one of the currently authorized session types. (I'd rather invalidate the old session, but the session middleware doesn't let me invalidate a session by user id)
Anyway, the problem with this is that there doesn't seem to be any way to get the req object into the deserializeUser function and thus I can't get the session id to check if the session is still valid.
Could this feature be added? Seems like it'd be simple enough to add an optional options object similar to how the strategies do it for getting the req object into the authenticate callbacks... Also, if you have an alternate suggestion, I'm certainly open to that as well =]
The text was updated successfully, but these errors were encountered: