EmailLinkedInGoogle+TwitterFacebook

This week Kiva Engineering team did a beta release of its protected API set. Through these APIs applications can fetch more in depth information about a specific lender. This ability in turn will help consuming applications present more accurate and meaningful analysis. Coincidentally this was exactly the API set I was waiting for. On my KivaSearch tool I was in the middle of implementing some ‘Me’ filters. What ‘Me’ filters were to do was to let the users choose search criteria like ‘Find loans that match my previous lending habits’, ‘Find Loans that are to countries other than those I have lent to’, ‘Find loans from my preferred MFIs’, etc. As you can imagine the pivotal data for these criteria is “Who is ‘I’”?. In the absence of the protected APIs and its oAuth implementation all I could do was to help the user find her own lender_id. This was error prone, easy to spoof and most importantly frustrating. With the oAuth implementation available from Kiva, all my user needs to do is to click on a ‘Login’ link and login to Kiva using her regular credentials. Just as in any oAuth implementation, she should then authorize KivaSearch to access some information on her behalf. Very easy and straight forward.

As the first step to implementing this feature I put together a wrapper NodeJS library for Kiva oAuth APIs. I am only following the route to allow a web application to authorize it with Kiva. For devices it might be a slightly different route. If that is what you need please feel free to fork the code.To demonstrate the usefulness of this library I also have written a demo application and it can be accessed online at KivaOauth Demo. The demo lets you login to kiva and and fetch back and display your full name and current account balance. You need a Kiva account to use it anywhere beyond the landing page. So, if you don’t have a Kiva account yet this is a good time to get one as well :) .

  • To use this library these are the steps.Decide on the access rights your application needs on behalf of the user. Currently the access rights are the following

“access” ==> Basic information about the user account, Name, lender id
“user_balance” ==> Current account balance at Kiva in USD.
“user_email” ==> User’s registered email.
“user_anon_lender_data” ==> Ability to fetch loan information for this lender even for the loans she lent anonymously.
“user_loan_balances” ==> Current payback status and balances of each of the user’s loans.

exports.scopes = [
    "access",
    "user_balance",
    "user_email",
    "user_anon_lender_data",
    "user_loan_balances"
  ];

myapp.js

  • Define two HTTP routes for your application
  1.  authorize url (eg. /auth/kiva) : This is where the user lands when he is starting the authorization process. From this point user will be redirected to Kiva and on successful authorization she will be redirected back to your applications ‘callback’ url, which is..
  2. callback url (eg. /auth/kiva/callback) When the user lands here the response will include sufficient information for you know the user and the rights she has granted for your application. As a responsible developer on this step you should securely save this information and redirect user to the resource you wish her to access.
var kivaoAuth = new (require('./kivaoAuth.js')).$();
app.get('/auth/kiva', function(req,resp){
	if(!isAccessSet(req)){
		kivaoAuth.getOAuthRequestToken(req,resp);
	}
	else{
		resp.sendfile(__dirname  + '/public/checkstuff.html')
	}

});
app.get('/auth/kiva/callback',
	function (req, resp){
		kivaoAuth.getOAuthAccessToken(req,resp,function(data){
			var id = data.user_account.lender_id;
			access_tokens[id] = data;
			var crypted = kivacrypt.encrypt(id);
			resp.cookie('_appversion55667654', crypted, {maxAge: 60 * 60 * 24 * 365 * 1000, httpOnly: true});
			resp.sendfile(__dirname  + '/public/checkstuff.html')
		});
	}
);

snippet from app.js

In my callback execution for the demo application saves  ’access_token’ in an application level data structure  I also push an encrypted cookie into the client end with lender_id information. I am pushing cookie to the client to know the user on return. I am encrypting it to make sure that it is not tampered with especially since I am setting a very large expiration window for the cookie. Saving ‘access_token’ to the local store will help me fetch back user specific ‘access_token’ when she returns.

  • Register your application along with a valid callback url.

Remember that it is not Kiva Server, but your client browser doing the ‘callback’. So the callback url need not be a public one. You can make it look like a public one easily by modifying your hosts file. I have a small description on it within the README. For eg. My Callback url looks like http://test.bonigopalan.com:3000/auth/kiva/callback , it exists only on my localhost and test.bonigopalan.com points to 127.0.0.1.

kiva-app-account

  • Input your application’s identity information into myapp.js
exports.appid = "com.bonigopalan.test";
exports.clientid="com.bonigopalan.test";
exports.clientsecret = "pxIvokqHsvogHdvjDCArwyqvdxrMEkrC";

exports.scopes = [
    "access",
    "user_balance",
    "user_email",
    "user_anon_lender_data",
    "user_loan_balances"
  ];

exports.callbackURL = "http://test.bonigopalan.com:3000/auth/kiva/callback";

  • Create a file named cryptkey.js as per the provided template cryptkey.template.js

You are good to go now. All basic scaffolding is done.

kivacrypt.js is my rudimentary encryption library. You are encouraged to modify it to match your paranoia level. I ain’t checking in my cryptkey.js either. You have to create that file manually using cryptkey.template.js. See, I know a thing or two about paranoia. At least a few friends from my past are sure to chuckle here.

Within the demo application access tokens are managed in a very rudimentary way. It is only representing a persistent data store. You should decide on either an encrypted database table or a redis cache for keeping this safe but easily accessible.

var access_tokens = [];
function isAccessSet(req){
if(!getUser(req)){
return false;
}
return true;
}

function getUser(req){
var key = req.cookies._appversion55667654;
if(!key) return null;
return access_tokens[kivacrypt.decrypt(key)];
}

function deleteUser(req){
var key = req.cookies._appversion55667654;
if(!key) return;
delete(access_tokens[kivacrypt.decrypt(key)]);
}

Snippet from app.js

Now, you are all set to use some protected APIs on Kiva end. For the demo purposes I am using the one to find current user balance.

app.get('/balance',function(req,resp){
		if(!isAccessSet(req)){
			resp.send("Not authorized",401);
			return;
		}
		kivaoAuth.getBalance(getUser(req).access,function(data){
			//console.log(data);
			resp.send(data);
		});
})

The corresponding client call is from checkstuff.html and it looks something like this. It uses Jquery to make the AJAX call and do STUFF.

    	function checkBalance(){
            $.ajax({
              url: "/balance",
              processData: false,
              contentType: "application/json",
              method:"GET",
              success:function(data) {
              	$('#kiva_balance').text(JSON.parse(data).user_balance.balance);
              	$('#balancemodal').modal('show');

              },
              error:function(error) {
              	$(location).attr('href','/');
              }
            });
    	}

Action behind the scenes

Plenty of work happens behind the scenes, wrapped cozily within kivaoAuth.js. It uses values from myapp.js to identify application credentials. It then uses a great node module, node-oauth to first request a ‘request_token’. The received request_token is short lived. So it uses the request_token and exchanges it with kiva for a long lived ‘access_token’. At this stage your application is authorized at Kiva to fetch data using credentials in ‘access_token’ (along with access_secret). When you query kiva using an access_token, specific to an user, to kiva your application represents the user. Your token is valid till the time user revokes her decision to allow your application rights to her information at Kiva.

You can experiment will all these features at the demo app. But first you need a Kiva account. Go for it!

The code discussed here is here on Github as well.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Post Navigation