jaredhanson / oauth2orize

OAuth 2.0 authorization server toolkit for Node.js.
https://www.oauth2orize.org?utm_source=github&utm_medium=referral&utm_campaign=oauth2orize
MIT License
3.47k stars 469 forks source link

Not use sessions #146

Open mfrachet opened 8 years ago

mfrachet commented 8 years ago

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 ?

coolaj86 commented 8 years ago

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)

jaredhanson commented 8 years ago

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.

thomasleduc commented 8 years ago

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 :'(

heby281 commented 8 years ago

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?

thomasleduc commented 8 years ago

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.

jaredhanson commented 8 years ago

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.

blanchma commented 6 years ago

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

2coo commented 3 years ago

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