oauth2orize icon indicating copy to clipboard operation
oauth2orize copied to clipboard

Not use sessions

Open mfrachet opened this issue 8 years ago • 8 comments

I m having some troubles when trying to implement an oauth2orize server without sessions.

Even if I set passport strategy with session:false, oauth2orize throw me an exception telling that I didnt registered a session middleware, what I absolutely don't want.

How can I avoid this behaviour ?

mfrachet avatar Nov 28 '15 07:11 mfrachet

I ran into this myself a while back. You have to stub out req.session yourself due to the tid (transaction id) variable. You can do this in a middleware just before. I wish I still had that code, but it's buried about two months back somewhere in my revision history.

I've done a complete rewrite of oauth2orize which I've called oauth3orize and I'll be making the code available publicly next week (got a little behind this week with travel for thanksgiving and all).

It's very lightweight and extensible, only focusing on the required interaction necessary for oauth2 compatibility at the interface layer without regard for nuances of internal implementation details of the specification.

I'll post back when I have it available. (the current repo is just an empty stub)

coolaj86 avatar Nov 28 '15 07:11 coolaj86

There's a branch, txn-stores, which is where work is being done to abstract the session requirement, making pluggable transaction stores that don't rely on sessions.

jaredhanson avatar Nov 28 '15 17:11 jaredhanson

Hi @coolaj86, I was going to stub the session when I saw your comment. The repo still empty. Can you post your middleware before the decision ? I still don't understand why we have to put the client in session. We just can get the client from the transaction_id in a mongo collection for exemple, can't we ?

@jaredhanson It seems the branch is cancelled :'(

thomasleduc avatar May 03 '16 14:05 thomasleduc

Hi @jaredhanson , in branch txn-stores, this code still exist in middleware/authorization.js: if (!req.session) { return next(new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?')); }. We only need session when use middleware transactionLoader and decision. If we send response immediately, we don't need session. Can I fix this issue and push it into master?

heby281 avatar May 06 '16 03:05 heby281

I use MongoDB for the moment. Because I want my api to run on multiple servers. The aim is to fool the solution without modify it.

Here my document MongoDB OAuthTransaction :

{
  user, // to make the document like session (according to the user)
  tid, // the transaction id
  trans, // the transaction store in session['authorize'][tid]
}

After the /api/authorize route, before render the authorize page, I store the req.session['authorize'][tid] in trans field in a middleware called saveTransaction in my oauth2Controller.

/**
 * Transaction : Fool the session transaction logic of oauth2orize by saving it in database
 */
exports.saveTransaction = function(req, res, next) {
  var user = req.user,
      transaction = req.session['authorize'][req.oauth2.transactionID];

  if (user && user._id && req.oauth2.transactionID) {
        trans = new _db.OAuthTransaction();
        /* ... */
        trans.user = user._id;
        trans.tid = req.oauth2.transactionID;
        trans.transaction = transaction;

        trans.save(function (error, result) {
          debug('trans save : ', error, result);
          return next();
        });
    });
    return;
  }

  return next();
};

Before the /api/authorize/decision route, after authenticate the user with jwt token in post, I look for an OAuthTransaction with a user and a tid in a function called stubTransaction. I put back the trans field in req.session['authorize'][tid] and launch the server.decision().

/**
 * Transaction : Put the session back to transaction
 */
exports.stubTransaction = function(req, res, next) {
  var user = req.user,
      tid = req.body.transaction_id;

  _db.OAuthTransaction.findOne({user:user._id, tid:tid}, function(err, trans) {

    if (!trans || !trans.transaction) {
      return res.send(403, {err:'Transaction missing in Oauth2 process'});
    }

    req.session['authorize'] = req.session['authorize'] || {};
    req.session['authorize'][tid] = trans.transaction;

    trans.remove();
    return next();
  });
};

It's not really clean but it do the job. Since my mongoDB databases are shared with all the api instances, it's almost stateless.

thomasleduc avatar May 06 '16 07:05 thomasleduc

There's now a txn-stores-3 branch with a pluggable transaction store interface. I will be merging this and publishing to npm as soon as I have test cases. Anyone who wants to store the OAuth transaction outside of the session can implement a custom transaction store.

jaredhanson avatar May 10 '16 21:05 jaredhanson

@jaredhanson I don't see documentation about txn-stores-3

blanchma avatar Aug 15 '18 22:08 blanchma

Is there any repo that is implemented oauth2 without session? @jaredhanson

2coo avatar Nov 13 '20 09:11 2coo