The Authentication Headache

Authentication involves setting cookies, handling incoming & outgoing requests, maintaining sessions and securely managing passwords. Finding all this an unnecessary headache, I’d left this for as late as possible. Instead, I’d been using a temporary text string as username all across the app (client & server) and using it to store data.

Somehow, I always thought that once I’d implemented authentication, integrating the user details instead of that text string would be a quick job. How wrong I was.

Thanks to GAE’s in-built users.User object and connected federated login options, it barely took me half a day to implement authentication, create a page for it and connect it to the database. Then it took me another 2 days to replace all references to that text string – sometimes passed as argument, other times coded, other times completely absent – with a proper uid, uname combo. It needed working-over twice and a lot of thought midway into the second do-over, but also realised that localStorage data didn’t need any user identity information. In fact, the only client side entity that needs any user information is the Logout link. Anyway, have got the system to work with user auth and tested it with multiple users.

Though it’s working with the current setup, I’m afraid the non-xhr GET & POST functions are broken. I’d been planning to get rid of POST and use GET in its current serve-empty-html format, till I realised that my own trusty phone – the Nokia E71 – may not support most of those javascript functions, specially xhr. So, will likely be working on integrating it again with a backup index.html template for non-login non-xhr requests.

Online/Offline Daemon

Completed a big task on Friday, though not the way I wanted it – background, auto synchronisation of notes (including changes, deletions, etc) between server and browser app.

HTML5 has introduced the powerful features that provide in-built features for managing actions such as synchronisation when the browser detects an internet connection.

[sourcecode language=”javascript”]
if(navigator.online){
//do sync here
} else {
//store data offline
}

document.body.addEventListener("online", function () {
// do sync here
}, false);

document.body.addEventListener("online", function () {
// store data offline
}, false);

[/sourcecode]

Unfortunately, these features aren’t completely supported, or even uniformly implemented across browsers and, thus, are hardly usable in the current state.

All server requests in my app are implemented through xhr. So, I’m tapping into it and using this workaround:

  1. If an xhr call fails, an alternate function is called which:
  1. Sets a global variable to ‘offline
  2. Calls equivalent local functions which edit/create/delete/list from localStorage
  3. Starts a daemon using setInterval() that checks every sends a ‘Ping‘ xhr request to check if a server connection is available again
  • When the daemon can connect to server, it:
    1. Sets the global variable to ‘online
    2. Starts a function that syncs all local changes to server and then downloads a fresh list from server
    3. Kills the daemon using clearInterval() call

    There are quite a few problems with this approach. The ones I’m worrying about right now are:

    1. Memory, CPU and battery usage by that artificial daemon, specially on mobile devices.
    2. Unnecessary load on the server from handling those Ping requests, even though there’ll be only one successful one for every connect.

    Though, compared to the browser ‘online / offline’ properties, this approach has one advantage too – it can also handle instances when the internet connectivity is up but my server / app is down.

    One change I’ll probably be doing is fetching only the header instead of pinging the app and checking result – It’s faster and might be lighter on the server (need to check this bit). Got the idea for this from this blog post.

    [sourcecode language=”javascript”]
    x.open(
    // requesting the headers is faster, and just enough
    "HEAD",
    // append a random string to the current hostname,
    // to make sure we’re not hitting the cache
    "//" + window.location.hostname + "/?rand=" + Math.random(),
    // make a synchronous request
    false
    );
    [/sourcecode]

    Still, that doesn’t make up for a native browser capability to tell the app when the network connection has gone down. Waiting for it…

    Continue reading

    A night of suffering

    The refactoring continues.

    After moving all xhr calls from JSON to html, backed by django templating on the server, realised that in order to implement offline, localStorage based system, I still need to generate html at the browser. I could have taken the old, working version with html generating via js strings but it will need another load of work when the design of page starts changing. So, spent the night researching browser-based templating systems. Have shortlisted three – mustache, Closure and Pure. All seem to be taking strange approaches. So far Closure seems to be the one I’ll go with, but the final call will happen tomorrow after some more research.

    Meanwhile, the pen drive finally seems to have filled up, so can’t work off it anymore. Have saved all that I wanted to in dropbox and in bookmark syncs. Gonna reformat and recreate the live USB now so I can start working again tomorrow. The new laptop still isn’t featured on dell website though people have started talking about it on twitter. Seems like it’ll be another week or so before I finally get my hands on it and can create a full development environment. The new liveUSB should last till then, I hope.

    Time to sleep now. Ciao.

    POST using xmlhttprequest

    Struggled with this all of yesterday and earlier today. Finally, discovered what seems to be a bug in the implementation (or something that specs missed):

    When passing arguments / parameters with a POST request, the javascript: xmlHttpRequest function seems to truncate/modify the first and last arguments.

    So, now I’m sandwiching the actual arguments between empty buffer parameters and its working.

    Can’t believe how many hours I’ve wasted on this one issue, and that no one addresses it anywhere on the web.

    Anyway, the whole app is now working via ajax, and, as a result, is lightening fast. Now, need to include offline storage of files (manifest) and data (localStorage). Before that, wondering if I should do a split version and test passing the whole formatted html div instead of just JSON objects in response to xhr requests.

    The Rockstar Weekend

    Learnt more, importantly more practical stuff, about ajax, xhr and how to use it within Google App Engine from this post. Then went about restructuring (refactoring?) the code on both sides – client & server – to enable it. Didn’t require much work on the server-side. During the previous round of restructuring, I’d enabled single url calling with a sorter function spreading requests to relevant functions. That helped since I’m now just calling the same function for xhr calls and returning the results as a JSON, instead of a formatted HTML page.

    On the client side, had to redo nearly the whole code again. The main HTML is now just a plain page with a header and a body div. Everything is written into it by js functions. This has meant I can’t use the powerful django templates on server-side to generate that html. And that’s a pain. Still thinking if I should just give up and instead of returning the JSON objects, return the formatted html code for relevant div in response. Might try it too and then decide on the outcome based on whichever approach works faster and lighter. Anyway, using the xhr-JSON method, have already got the GET functions to work. The two POST functions are still standing out. Was working on them when Rags woke up and interrupted my work day. Still, glad that I woke up at 4 and immediately got to work. Gave me 6-7 hours clean before she decided to rock my day.

    The rest of weekend was almost wasted in work terms. Saw Rockstar, the hindi movie, in the evening. Loved it. Then met JD&R for dinner in Chinatown. Came home and, after briefly checking G+, twitter & techmeme, dropped dead on the bed.

    Today’s been uber-lazy. Woke up at 12 after 11 hours of sleep but got out of bed another 90 mins later. That too when Rags brutally pushed me outta bed. Spent the rest of day watching F1, listening to Rockstar OST over and over again, and reading articles over at gigaom and businessinsider. Researched the biggest player in CldNts industry right now. Followed their founder CEO on twitter. Also followed Naval Ravikant, the angellist founder, on twitter. Fella seems interesting. Finally read a businessinsider story on Ron Conway. Scary.