ammmir / node-oauth2-provider

A simple customizable OAuth 2.0 provider (server) for node.js.
MIT License
628 stars 161 forks source link

Setting up oauth on express #25

Closed norman784 closed 11 years ago

norman784 commented 12 years ago

In the example there is a part of the script that are not working

express.createServer(
  express.logger(),
  express.bodyParser(),
  express.query(),
  express.cookieParser(),
  express.session({store: new MemoryStore({reapInterval: 5 * 60 * 1000}), secret: 'abracadabra'}),
  myOAP.oauth(),
  myOAP.login(),
  express.router(router)
).listen(8081);

And my script its (using express 3.0.0rc5)

app.configure(function(){
    app.enable('jsonp callback')
       .use(express.static(__dirname + '/public'))
       .set('view'          , __dirname + '/views')
       .set('view engine'   , 'jade')
       .use(express.bodyParser())
       .use(express.cookieParser())
       .use(express.methodOverride())
       .use(express.session({secret : config.salt}))
       .use(gzippo.compress())
       .use(oauth.oauth())
       .use(oauth.login())
       .use(app.router)
})

But seems that none of the oauth provider functions are called, the script its just like the example. The example just throw me

simple.js:137
  express.router(router)
          ^
TypeError: Object function createApplication() {
  var app = connect();
  utils.merge(app, proto);
  app.request = { __proto__: req };
  app.response = { __proto__: res };
  app.init();
  return app;
} has no method 'router'
    at Object.<anonymous> (simple.js:137:11)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)
norman784 commented 11 years ago

nvm.. I figure out

// simple server with a protected resource at /secret secured by OAuth 2

var OAuth2Provider = require('oauth2-provider').OAuth2Provider,
           express = require('express'),
       MemoryStore = express.session.MemoryStore;

// hardcoded list of <client id, client secret> tuples
var myClients = {
 '1': '1secret',
};

// temporary grant storage
var myGrants = {};

var myOAP = new OAuth2Provider('encryption secret', 'signing secret');

// before showing authorization page, make sure the user is logged in
myOAP.on('enforce_login', function(req, res, authorize_url, next) {
  console.log('enforce_login')
  if(req.session.user) {
    next(req.session.user);
  } else {
    res.writeHead(303, {Location: '/login?next=' + encodeURIComponent(authorize_url)});
    res.end();
  }
});

// render the authorize form with the submission URL
// use two submit buttons named "allow" and "deny" for the user's choice
myOAP.on('authorize_form', function(req, res, client_id, authorize_url) {
  console.log('authorize_form')
  res.end('<html>this app wants to access your account... <form method="post" action="' + authorize_url + '"><button name="allow">Allow</button><button name="deny">Deny</button></form>');
});

// save the generated grant code for the current user
myOAP.on('save_grant', function(req, client_id, code, next) {
  console.log('save_grant')
  if(!(req.session.user in myGrants))
    myGrants[req.session.user] = {};

  myGrants[req.session.user][client_id] = code;
  next();
});

// remove the grant when the access token has been sent
myOAP.on('remove_grant', function(user_id, client_id, code) {
  console.log('remove_grant')
  if(myGrants[user_id] && myGrants[user_id][client_id])
    delete myGrants[user_id][client_id];
});

// find the user for a particular grant
myOAP.on('lookup_grant', function(client_id, client_secret, code, next) {
  console.log('lookup_grant')
  // verify that client id/secret pair are valid
  if(client_id in myClients && myClients[client_id] == client_secret) {
    for(var user in myGrants) {
      var clients = myGrants[user];

      if(clients[client_id] && clients[client_id] == code)
        return next(null, user);
    }
  }

  next(new Error('no such grant found'));
});

// embed an opaque value in the generated access token
myOAP.on('create_access_token', function(user_id, client_id, next) {
  console.log('create_access_token')
  var data = 'blah'; // can be any data type or null

  next(data);
});

// (optional) do something with the generated access token
myOAP.on('save_access_token', function(user_id, client_id, access_token) {
  console.log('save_access_token')
  console.log('saving access token %s for user_id=%s client_id=%s', access_token, user_id, client_id);
});

// an access token was received in a URL query string parameter or HTTP header
myOAP.on('access_token', function(req, token, next) {
  console.log('access_token')
  var TOKEN_TTL = 10 * 60 * 1000; // 10 minutes

  if(token.grant_date.getTime() + TOKEN_TTL > Date.now()) {
    req.session.user = token.user_id;
    req.session.data = token.extra_data;
  } else {
    console.warn('access token for user %s has expired', token.user_id);
  }

  next();
});

var app = express()
app.configure(function(){
  app.use(express.logger())
  .use(express.bodyParser())
  .use(express.query())
  .use(express.cookieParser())
  .use(express.session({store: new MemoryStore({reapInterval: 5 * 60 * 1000}), secret: 'abracadabra'}))
  .use(myOAP.oauth())
  .use(myOAP.login())
  .use(app.router)
})

app.get('/', function(req, res, next) {
  res.end('home, logged in? ' + !!req.session.user);
});

app.get('/login', function(req, res, next) {
  if(req.session.user) {
    res.writeHead(303, {Location: '/'});
    return res.end();
  }

  var next_url = req.query.next ? req.query.next : '/';

  res.end('<html><form method="post" action="/login"><input type="hidden" name="next" value="' + next_url + '"><input type="text" placeholder="username" name="username"><input type="password" placeholder="password" name="password"><button type="submit">Login</button></form>');
});

app.post('/login', function(req, res, next) {
  req.session.user = req.body.username;

  res.writeHead(303, {Location: req.body.next || '/'});
  res.end();
});

app.get('/logout', function(req, res, next) {
  req.session.destroy(function(err) {
    res.writeHead(303, {Location: '/'});
    res.end();
  });
});

app.get('/secret', function(req, res, next) {
  if(req.session.user) {
    res.end('proceed to secret lair, extra data: ' + JSON.stringify(req.session.data));
  } else {
    res.writeHead(403);
    res.end('no');
  }
});

app.listen(3000);

function escape_entities(s) {
  return s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}

This works with express 3.0.0rc5, also is the pull request #18