For redirect based OAuth 2.0 authorization code flow, a user agent like a web browser or mobile phone needs to be involved. In the light-oauth2 repository, we have provided a login-view single-page application based on React. In this section, we are going to walk through the application to show users the implementation details.
This single-page application should be hosted in the light-router instance as a virtual host along with a customer’s application. From the customer’s application, a login button will redirect to this login-view application URL with some query parameters like username, password, and client_id, etc.
The login-view is based on the redirect Authorization Code flow for Single Page Applications. We will provide another example of the mobile application later.
The original application will have a log in button or menu item. Once it is clicked, the browser will redirect to the login-view application, which is based on the React.
The login-view will accept username and password to invoke light-oauth2 code service.
The code service will redirect to the /authorization?code=xxx to the browser.
The browser will invoke the above API which is handled by StatelessAuthHandler in light-spa-4j
The StatelessHandler will use the code query parameter, client_id, client_secret saved on router server to get access token and refresh token from the light-oauth2 token service. The StatelessHandler will save the access token, refresh token, csrf, userId, roles, and userType as cookies. The access token and refresh token are HttpOnly and Secure, so the browser application cannot access them. The handler also returns the redirectUri, denyUri, and scopes.
The login-view will use the response to display a consent page will a list of scopes and ask users to DENY or ACCEPT the grant.
If DENY button is clicked, all the cookies will be removed, and the browser will be redirected to the denyUri. The entire flow is canceled.
If ACCEPT button is clicked, the browser will be redirected to the redirectUri.
All subsequent calls to the light-router server from the original SPA will carry all the cookies to the request. The StatelessAuthHandler will capture the access token and refresh token and put the access token into the request header to invoke downstream APIs.
If the access token is expired or about to expire, The StatelessAuthHandler will renew a new token and put the new one into the request header.
To prevent CSRF(Cross-site request forgery), the original application must get the csrf cookies and put it into the request header for each request.
Above is a simplified flow without a lot of detail for easy to understand.
The source is generated with create-react-app, and the main logic is in the App.js file. The component accepts query parameters from the redirect and uses the useState for the state, clientId, userType, and redirectUri.
It renders a login form that accepts username, password, and remember. Once the submit button is clicked, the component will fetch the /oauth2/code to start the Authorization Code flow. If everything is OK, the light-oauth2 code service will redirect to the redirectUri registered in the client registration. In most of the cases, it will be your application domain with https protocol and the path /authorization.
Before using the SPA, you need to build the application and deployed as a virtual host on an instance of light-router. There are three different build options depending on where the light-oauth2 services are located.
If you deploy the light-oauth2 services on your own behind the light-router, then you can use the following command to build.