Friday, August 9, 2019

Understanding SPA - Single Page Web Application

Traditional web applications (like ASP.NET applications) consist of many html pages, when users navigate from page to page, a new http request is sent to server and the server will send a new html page back to client for rendering. As a result, the web app has to maintain the state information in session data, as each html page loaded in browser does not maintain or inherit any information from previous html page.

The page reloading is bad for user experience and also increases the complex to maintain the application state when crossing different html pages. That is the reason of creating of SPA (single page application).

For Single Page Web Application, there is only one html page is loaded in the entire life of the application life time. So it is just like running a desktop application, so that the state maintained in  application is always valid. The html page is just like an empty container, and when users navigate to different UI pages, it just replaces the content in the empty html page.

Many client side javascript frameworks have been created for this purpose, such as Angular, React, VUE. So that it helps developer to create and manage pages shown on the empty pages. Hybrid framework, such as cordova or Ionic, also use the same SPA approach. Correspondingly, the WebAPI and microservice are applied on server side to just respond to client with the required data for xmlhttpreqeust without returning the whole html page to client.

One challenge to Single Page Application is, for browser, the back and forward button is only applying to page navigation between html pages, as those buttons were created for traditional web apps. However, for single paged application, only one html page is loaded, so developers must use javascript framework to properly manage the navigation history, so that user can still use the back and forward button to navigate between the different UI content as if they are loaded as separate html pages. That is one major reason when javascript framework, like Augular is used for creating SPA applications.  

Authentication for SPA is also different from traditional web app. For SPA, all web resource (like html and script, css files) will be loaded on browser, so there is no point to secure those files. The purpose of user authentication and authorization (for example, with angular Auth Guard) is only needed when SPA web sends requests to backend API services. As a result, although SPA app may include the logic of user authentication and authorization (for example, doing an oAuth or SAML login), the purpose of that is only for getting the app ready to send API requests to backend, so SAP app itself does no need to validate the authentication result, such as checking whether the oauth token will be accepted by backend API service or not, instead it just needs to go through the login process, and get the tokens, and  pass the token with the backend API requests, it is the backend api service's response to actually validate the token and decide whether allow the SPA app to call the backend service API. 

For example, when configuring oauth2 authentication on Azure, both backend API app and frontend SPA app should be registered in Azure AD. However, user will never directly login and authenticate to the backend api app. Instead, the backend API app should expose an API, and define a scope for the exposed API. Also, in the Azure AD registered frontend app, it should add a permission to the exposed API by backend API app registration. Then in the frontend application implementation, configure the frontend app's client id, and authorization url, authorization grant type, token url, so that the SPA app can authenticate the user and get the JWT token. The JWT token should include a claim of backend API scope information, the JWT tocken can be passed in http request's authorization header to the backend API, so backend API can validate the JWT token to decide whether the client request has the required permission.

1 comment: