How to Build a Custom Login Page for RStudio (Posit) Connect


It’s hard to argue with the fact that user experience can make or break digital products, Shiny apps included. A custom login page is one of those early UX touchpoints with the potential to infuse users with brand awareness from the get-go. But achieving that ultimate first impression when hosting your Shiny app with RStudio Connect is a challenge. Happy Cabbage Analytics wanted more for their users and so they reached out to Appsilon to explore custom options for their login page on RStudio Connect.

This article will show you how to do the same. Read on to take your login page to the next level.

Note: At the time of writing this article, Posit PBC was RStudio PBC. We use RStudio and Posit interchangeably in this text (e.g. RStudio Connect == Posit Connect).


Custom login page for Connect calls for custom development processes

RStudio Connect is a mighty offering for companies looking for an all-in-one hosting solution. Happy Cabbage relies on RStudio Connect’s user management and password authentication to grant access to their Shiny apps. However, the customer experience that Happy Cabbage envisioned went beyond the default landing page, which had RStudio logos and additional features they didn’t need.

The project goal was a clean and simple login user interface with the client’s branding, to keep the user experience as smooth as possible. The Appsilon team loves a good Shiny challenge and the development process we proposed went far beyond the standard procedure.

Research and experiments

Being an RStudio full-service certified partner, we are well-versed in their publishing platform – RStudio Connect. It has a feature that allows you to customize the landing page to some extent, but we needed next-level options. The stock customization options don’t translate to significant changes in the interface design and the RStudio branding remains.

It was time to look for a viable alternative. We briefly considered using proxied authentication to customize user authentication and management. We weren’t convinced this was the most efficient way to achieve our goals. So we decided to stick to the current infrastructure and get creative.

One of the experiments we ran involved some reverse engineering and proved particularly promising. The idea was to build a Shiny app working as a landing page customers can use to log in and out of. With this option, we’d have complete control over the look and feel of the customer login page. Which was exactly what Happy Cabbage needed.

The authentication mechanism in RStudio (Posit) Connect

To understand this solution, let’s take a step back and look at how the default RStudio Connect landing page works first.

Server connection

The user visits the URL for the client’s apps hosted with RStudio Connect. The server replies with a web page (HTML and JavaScript) and loaded into the browser.

 

User login

After the user enters their credentials and hits “log in”, the browser sends a login API request. If the credentials are valid, RStudio Connect replies with an HTTP-only session cookie, which will serve as a “proof of identity” for the browser.

 

API calls

The session cookie is attached to all subsequent requests. The JavaScript in the browser continues to load the page by making multiple API calls to fetch the username, list available content, etc.

 

 

Access to content

The session cookie is also sent when the user requests to open a Shiny app. RStudio Connect decides whether the user is authorized to run it, based on the user identity and access settings of the app.

How to customize login page in RStudio (Posit) Connect

The key takeaways from the research phase helped us understand both the constraints and the opportunities that come with the RStudio Connect API.

  1. To access apps on RStudio Connect, the browser needs to get the session cookie somehow.
  2. The login request doesn’t need to be made by the default landing page. It only needs to originate from the same domain. This is because the session cookie is HTTP-only and cannot be accessed by JavaScript.

For example, the JavaScript of a Shiny app running on RStudio Connect could make the login request and the session cookie it receives will work just fine. The R process which runs the app is not involved in the authentication. This happens entirely between the browser and the API.

Solution outline

Our idea for the custom login page for Happy Cabbage was to create a Shiny app that could replace the default RStudio Connect landing page. The app’s JavaScript would make an API request to log the user in and get a session cookie. The subsequent requests allow fetching the user name, list content, etc.

And so we return to the reverse-engineered part. To log in, we needed to use an API endpoint that is not listed in the official documentation. We also relied on another undocumented fact: the session cookie is sufficient to access the API for subsequent requests.

Architecture

We wanted to keep the login page simple, with just a few vital functionalities:

  • log in
  • log out
  • get username
  • list content
  • change password

All the processes listed above happen between the browser and the API. And R/Shiny doesn’t really need to be involved. In fact, we decided it’s best to implement the whole login page in JavaScript and only use R/Shiny as a thin wrapper to make deployment to RStudio Connect easier:

This way, the Shiny app loads the landing page, which was built using Create React App as a foundation. It’s a fairly simple React app, styled with Bootstrap and Sass. It uses axios to make API requests with the following simple configuration:

The second line ensures that the session cookie is attached to all requests, while the remaining lines handle the XSRF protection built into RStudio Connect.

In the end, you can deploy the app like any other Shiny app. You should enable access for all users (no login required) so all new customers can effectively use the app to log in.

 

Optionally, we can also add a neat Content URL.

 

Outcome: Custom Login Page for RStudio (Posit) Connect

What you can see below is a slick custom login page that takes Happy Cabbage customers to the aggregated view of the Shiny apps at their disposal. The apps and logos are fetched dynamically from the RStudio Connect instance.

 

Happy Cabbage Analytics can continue to scale its offering while enjoying the advantages brought by the customization:

  • No superfluous features to steal user attention from the login procedure.
  • The minimalist design makes the solution elegant and reduces user friction.
  • Logos and fonts are fully consistent with the brand identity.

With Appsilon clearly having the expertise and the skill set that we need, we can get a lot of stuff done quickly on the front end.” – Andrew Watson, CEO of Happy Cabbage Analytics

Custom solutions from R Shiny innovators

At Appsilon, we take pride in our R Shiny expertise and treat each challenge as an opportunity to grow our know-how. From pioneering the space of enterprise Shiny dashboards and speeding up Shiny apps to creating bespoke open source packages – our custom solutions keep pushing the limits of Shiny app development. Whenever your data science team needs a lightning-speed PoC or struggles with making your Shiny app production-ready, let us know. Our engineers are here to support you every step of the way.