Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep node-dbox token between page refreshes in NodeJS/Express

Im trying to put together a little application using NodeJS, node-dbox and Express. When requesting for DropBox authorization - it's a 3 step process, first need to get request_token, then user authorizes them visiting dropbox page, and only then request for access_token, based on request_token and the fact that user has authorized request.

However, by the time I served the page for step 1 and 2 (getting request_token, and providing user with url) - request_token instance is gone!, so in step 3 I can't request for an access_token, because it requires request_token being passed

I'm trying to save request_token in a cookie, but given that contains sensitive data, sending it to the client may not be such a good idea. Any ideas?

Simplified code is below:

(function() {
    var dbox = require('dbox'),
        config = require('easy-config'),
        express = require('express'),
        dboxApp = dbox.app(config.dropbox_credentials),
        app = express();

    app.use(express.cookieParser());

    app.get('/', function(req, res) {
        dboxApp.requesttoken(function(status, request_token) {
            res.cookie('request_token', JSON.stringify(request_token));
            res.send("<a href='" + request_token.authorize_url + "' targe='_new'>authorize via dropbox</a><br/>" + "<a href='/next'>next</a>");
        });
    });

    app.get('/next', function(req, res) {
        var request_token = JSON.parse(req.cookies.request_token);
        if(request_token) {
            dboxApp.accesstoken(request_token, function(status, access_token) {
                var client = dboxApp.client(access_token);
                client.account(function(status, reply){
                  res.send(reply);
                });
            });
        } else {
            res.send('sorry :(');
        }
    });

    app.listen(3000);

})();

bonus question: client is created with access_token, so either instance of client or access_token need to be maintained across page refreshes as well, whats the best approach?

like image 774
dark_ruby Avatar asked Nov 03 '12 17:11

dark_ruby


1 Answers

I managed to get it working by doing the following:

According to the Dropbox Developer reference you can provide a callback url by specifying it along with the request as stated here:

https://www.dropbox.com/developers/blog/20

https://www.dropbox.com/1/oauth/authorize?oauth_token=<request-token>&oauth_callback=<callback-url>

By storing the request token in the session and redirecting to the callback url you can then access the request token and be on your way. A couple of Express route handlers, passed a member id as a parameter, to request and then handle the response might look like this:

 linkAccount : function(req, res){
      var  memberId = req.params.memberId,
        appKey = 'MYAPPKEY',
        appSecret = 'MYAPPSECRET',
        dbox = require('dbox'),
        dboxApp = dbox.app({ "app_key": appKey, "app_secret": appSecret });


      req.session.dboxStore = {};
      req.session.dboxStore.dboxApp = dboxApp;

      dboxApp.requesttoken(function(status, request_token){
        req.session.dboxStore.request_token = request_token;
        console.log("request_token = ", request_token);

        res.redirect('https://www.dropbox.com/1/oauth/authorize?oauth_token='+request_token.oauth_token+
          '&oauth_callback=http://myhost.local/linksuccess/dropbox/'+memberId);
        res.end;
      });
    },

    linkSuccess : function(req, res){
      var memberId = req.params.memberId;
      var appKey = 'MYAPPKEY';
      var appSecret = 'MYAPPSECRET';
      var dbox = require('dbox');
      var dboxApp = dbox.app({ "app_key": appKey, "app_secret": appSecret });
      var request_token = req.session.dboxStore.request_token;

      dboxApp.accesstoken(request_token, function(status, access_token){
        console.log('access_token = ', access_token);

        Member.setAuthToken(memberId, 'dropbox', access_token, function(err, member){
          res.render('index', { title:'SUCCESSFUL DROPBOX AUTH' });
          res.end;
        });
      });
    }
like image 55
Lewis Avatar answered Sep 19 '22 17:09

Lewis