Developer Blog Series: Backend For Frontend (BFF) Authorization Code Flow

Published

The Backend for Frontend, or BFF, pattern has been the talk of the town in the world of microservices over the past few months. Since we are a microservice shop under the hood here at Blackbaud, I thought that I would take some time to talk about the BFF pattern and how it may relate to your applications as you work with SKY API.

 

But first, a quick overview of what the BFF pattern typically means. The BFF pattern is used in conjunction with microservices to prevent unintentional monoliths from forming in your code base. The idea is that when surfacing a set of functionality across different platforms, views, and use cases, the desired presentation and underlying need for information often changes. This means that if you have a single backend service to feed into all permutations of your application, you may end up with either an overly complex, non-performant set of endpoints as an attempt to provide the flexibility to handle all scenarios, or you may end up with a nasty web of diverse, highly specialized endpoints in a single service that becomes murky and difficult to maintain. Either way, you're not in a great spot moving forward.

 

The BFF pattern, on the other hand, recommends that general, reusable code be consolidated into common services, but any specialized code for a specific use case, platform, or view format is factored out into its own service. This service is then maintained by the team owning the end functionality to ensure they have the necessary domain knowledge to support it, while still encouraging them to leverage as much of the generalized functionality as possible to avoid rewriting the same code, particularly when it comes to common business logic and data access.

 

 

An Illustrative Example

 

If you have a web application for volunteer management, you may also have native applications for Android and iOS. This could potentially mean that the web application would support a more robust view of the data for more sophisticated configuration and back office functionality, while the native apps could behave more as a volunteer facing reference, or a day of event management application. While these are all very different applications, they could all reuse the same data store and generic services for the underlying entity shapes, user authentication, participant verification, and scheduling, as examples. There are, however, also some platform specific requirements and options that you may want to support.

 

Say you want to allow consumers to set up an iPad at their organization to allow volunteers to do onsite self-check-in process, and an Android app to allow volunteers to view and sign up for upcoming volunteer opportunities. In this scenario, you would likely have an array of services to manage your roster of volunteers, as well as manage your list of available opportunities. However, each of these views would also have a dedicated backend for custom tailoring and augmenting these common services. For example, although the Android application would likely call a generic endpoint for pulling information about the upcoming events, it requires a different level of detail than the back office list, and would likely further manipulate it before presenting it to the end user. It would need its own dedicated endpoints for managing volunteer credentials to scope their access, and perhaps allow users to view and get reminders for the upcoming events they've signed up for, as well as to view their previous volunteer experiences.

 

The iPad application, on the other hand, would want to present a higher level view of all participating volunteers for the given event, add their attendance to their back office record, and perhaps allow them to sign a waiver after checking in. These functions all run in a user agnostic manner, with limited access to the rest of the system. This application perhaps still needs a level of volunteer verification for mapping the waiver approval to the given volunteer, but this volunteer authentication process is likely much lighter weight than that of the Android application. In this scenario, Lukasz Plotnicki of SoundCloud would suggest creating a "mobile BFF" for handling the commonalities between the two mobile applications, such as volunteer authentication, with additional specialized services for each experience. The core of maintainable microservices would additionally encourage more common services for serving common entities and notions where appropriate. 

 

This example should clearly illustrate a different set of needs based on the given platform and use case, and the potential for ballooning if that functionality were it all to be included in a single monolithic service. At the end of the day, the intent of BFF, and the microservice approach in general, is to slice your code in such a way that it optimizes both domain specialization and reusability. When utilizing these patterns, instead of making the service slices purely horizontally by access layer, they additionally recommend vertical slices to better serve particular functions and platforms. To better demonstrate these additional slices of code and how they relate to SKY API, I would like to explore the idea of building a specialized Authorization Code Flow server application to support your SKY API client-side applications.

 

 

Improving User Experience With BFF Authorization Code Flow

 

As I'm sure all of you are aware, SKY API uses OAuth. User authentication and application authorization are required to access anything within any of our given APIs. Currently, we support a couple different flavors of OAuth flows, namely the Implicit Flow and the Authorization Code Flow. Although Implicit flow is typically the recommended approach for client-side applications, I would like to argue that it does not, in fact, offer the best possible experience for the end user.

 

Implicit flow tokens are relatively short lived and do not auto-refresh. This means that if your end user wants to interact with your application for longer than the duration of the token, they will have to manually reauthenticate the application when prompted to get a new authorization token, every single time the token expires. Although our tokens are currently set to last an hour, which is reasonable for most usage, manually reauthenticating can still get tedious if you're working with the application throughout the day or across several days in a given week. Similarly, automated processes will not be able to continue working without this manual intervention to approve the implicit access, which limits your application options.

 

Authorization Codes, on the other hand, are generated for server-to-server communication and can be stored and refreshed indefinitely using refresh tokens after the one-time consent approval process. This means that even if your application only runs once a day, by using a refresh token with your request the user will not have to reauthorize your application at run time.

 

So what does this mean for your client-side application? It means that you can potentially provide a much smoother, more enjoyable user experience by building a server side authorization Backend For supporting your client-side Frontend application. This backend application can be as light or as heavy as you want it to be in terms of the level of functionality built into it. Much like the suggested "Mobile BFF," if you support multiple client side applications, a single dedicated server-side authentication application, such as the one included in our related code sample, along with a database for token management, could be used for all of them. Alternatively, you could make your client-side application extremely light weight by relying more heavily on a dedicated backend service performing server side calls to support the specific application.

 

Suffice it to say, you've got options, but exploring a BFF style authorization server might be something worth considering when building client-side applications.

News SKY Developer Announcements 09/19/2016 10:45am EDT

Leave a Comment

Check back soon!

Share: