Skip to content

Instantly share code, notes, and snippets.

@joshbirk
Created February 1, 2012 22:33
Show Gist options
  • Save joshbirk/1719898 to your computer and use it in GitHub Desktop.
Save joshbirk/1719898 to your computer and use it in GitHub Desktop.
ForceDotCom Strategy for Passport
/**
* Module dependencies.
*/
var querystring = require('querystring'),
util = require('util'),
OAuth2Strategy = require('passport-oauth').OAuth2Strategy;
function Strategy(options, verify) {
options = options || {};
options.authorizationURL = options.authorizationURL || 'https://login.salesforce.com/services/oauth2/authorize';
options.tokenURL = options.tokenURL || 'https://login.salesforce.com/services/oauth2/token';
options.scopeSeparator = options.scopeSeparator || ',';
OAuth2Strategy.call(this, options, verify);
this.name = 'forcedotcom';
var self = this; // so we can set `_results` on the strategy instance
this._oauth2.getOAuthAccessToken = function(code, params, callback) {
// This form preserves the params sent as arguments, so grant_type and
// redirect_uri don't need to be re-specified.
var params= params || {};
params['client_id'] = this._clientId;
params['client_secret'] = this._clientSecret;
params['code']= code;
var post_data = querystring.stringify( params );
var post_headers = {
'Content-Length': post_data.length,
'Content-Type': 'application/x-www-form-urlencoded',
'Accept':'application/jsonrequest',
'Cache-Control':'no-cache,no-store,must-revalidate'};
this._request("POST", this._getAccessTokenUrl(), post_headers, post_data, null, function(error, data, response) {
if( error ) { console.log(error); callback(error); }
else {
var results;
results = JSON.parse( data );
self._results = results;
var access_token = results["access_token"];
callback(null, results["access_token"], results["refresh_token"]);
}
});
}
}
/**
* Inherit from `OAuth2Strategy`.
*/
util.inherits(Strategy, OAuth2Strategy);
Strategy.prototype.userProfile = function(token, done) {
done(null, this._results);
}
/**
* Expose `Strategy`.
*/
module.exports = Strategy;
@jaredhanson
Copy link

Here's my suggestions for improvement (comments noted in the code). The main focus is on getting rid of the need to replace Passport-OAuth's authenticate() function. I think that's doable by saving the results as an instance variable on the strategy, rather than modifying the function signatures of the callbacks.

// This code goes in the Strategy constructor.
var self = this; // so we can set `_results` on the strategy instance
this._oauth2.getOAuthAccessToken = function(code, params, callback) {
  // This form preserves the params sent as arguments, so grant_type and
  // redirect_uri don't need to be re-specified.
  var params= params || {};
  params['client_id'] = this._clientId;
  params['client_secret'] = this._clientSecret;
  params['code']= code;

  var post_data = querystring.stringify( params );
  var post_headers = {
    'Content-Length': post_data.length,
    'Content-Type': 'application/x-www-form-urlencoded',
    'Accept':'application/jsonrequest',
    'Cache-Control':'no-cache,no-store,must-revalidate'};

  this._request("POST", this._getAccessTokenUrl(), post_headers, post_data, null, function(error, data, response) {
    if( error ) { console.log(error); callback(error); }
    else {
      var results;
      results = JSON.parse( data );
      console.log(results);
      // save results, in the _results instance variable. This way we can use
      // it in userProfile() without having to replace authenticate()
      self._results = results;
      var access_token = results["access_token"];
      callback(null, results["access_token"], results["refresh_token"]);
    }
  });
}

// No need to replace authenticate()

Strategy.prototype.userProfile = function(accessToken, done) {
  // return the custom results saved by getOAuthAccessToken above
  done(null, this._results);
}

@joshbirk
Copy link
Author

joshbirk commented Feb 2, 2012

Thanks! Updated and tested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment