Fast User Switching for a LIMS Web App
Most laboratories have computers attached to various instruments where scientists can operate them and review the data they produce. Scientists are focused on processing samples which they move from instrument to instrument as they do their work. When more than one scientist works in a lab we find we have to trade convenience for accurate information recording and security. Users want to step up to a computer connected to, for example, a balance and just use it, but if they were not the last user of the instrument they would not be logged in. They need to take the time to switch to their account to keep data accurate, thus the tradeoff: convenience or integrity.
The typical solution of this problem, even in the most paranoid IT environments, is to create a “lab user” account that everyone shares. Users just log into all the computers as “lab user” and do their jobs.
Our Assay Capture and Analysis System (ACAS) has a web user interface and is used in laboratories to capture experimental data. When a user registers a sample, or measures an attribute like a material’s weight, we want to capture who made this measurement. This is important for data integrity, but also for intellectual property preservation when our software is used as an Electronic Laboratory Notebook. When users log in using a shared “lab user”, this important information is lost.
We were working with a client when this problem came up, and we solved it by offering “fast user switching”. This has been a feature of most desktop systems for about a decade, but we had not seen it in a web application. The requirements were:
- It has to actually be fast.
- If you’ve already started filling out a form, or collected instrument data, but haven’t saved yet, you have to be able to switch users without losing the data entered in the form.
- The list of users you can swtich to has to be controlled by a configurable security group. You will not be required to enter a password.
- If you switch users in one window, then all other windows and tabs should have their users changed as well.
One implication of these requirements is that the user switch request cannot lead to a page reload. On the other hand, reloading a page or opening a new tab should leave you logged in as the new user. Another implication is that for security we need to limit the list of users to those in the configured group. Because we cannot request a new password or reload the page to check a cookie and/or session, we will need to confirm that this switch is allowed on the server side. Finally, the last requirement means we need to push the login change to all open tabs.
Here is a short video showing how the implementation appears to the user. I also opened a console to highlight that a save request does indeed send the current user’s name.
If you are not interested in the tech aspects of this, you can stop reading now.
The Implementation
ACAS is a rich web application written in Coffeescript with Backbone.js. The whole application loads to the browser, then all operations are implemented by old-school AJAX communicating with our NodeJS middleware. We use a hybrid of REST and a sort of remote procedure call syntax that we developed for requesting computations. We found that this architecture limited real-time control of instruments as well as dynamic progress updates for long computations. To improve the user experience we added websockets using socket.io.
Websockets solves two of the requirements: operations are fast, and we can push the user change to other browser tabs. The actual implementation of this can be found in the ACAS git repository. The server side code is the most interesting, but you can also take a look at the client side code.
We use Passportjs to manage user authentication. We configured it to keep user details like the email, user roles, and other metadata in the session. We also pass this information to the client when it loads. When the user is changed we have to update the session information. This makes it so that new tabs and page reloads keep the new user. Also, all of the client’s AJAX calls are required to re-authenticate, so the session information needs to match. After the session is updated, the server uses websockets to push the new user metadata to the client, and also broadcasts it to the rest of the open tabs and windows.
Note that the implementation shown here is not sufficiently hardened to deploy the ACAS server to the cloud. This feature was built for an on-premisis installation where access to the server is tightly controlled.
Conclusion
ACAS Fast User Switching turned out to be one of those features that seemed hard to implement until I actually wrote the code, then turned out to be pretty straight-forward. This is when programming is most fun, especially because our users were so pleased and now save so much time in the lab.
I also want to thank the users and informaticists who requested this feature, helped test it, and gave invaluable feedback to make it better.