Mobile to Web App QR Code-based Authentication Using OutSystems
Hi everyone, in this article I want to share my latest challenge to myself this is for me to improve and always be in the tech trend. My goal here is to recreate or develop the Mobile to Web QR Code login which the user can just scan the QR Code on the Web app and authorize it to log in.
System Flow
- The web application will generate a QR Code that will based on the Token (SessionCode) and some relative data (TimeStamp, IP, Browser)
- A mobile app in which the user must be logged in so that they will be able to authorize the scanning request. Where the mobile app will be able to receive the Token and the other Data that will be used for server-side authentication.
- After the scanning, the mobile app then triggers a status push to the Web browser that the code has been scanned.
- From the Mobile information received will be sent back to the server for validation and authentication. And will inform the mobile app if valid or not.
- Then the user decides to authorize or cancel the request.
For other detailed implementations, you can check here https://subhajit-dutta.medium.com/mobile-to-web-cross-login-using-a-qr-code-877bc0c62994 an article by Subhajit Dutta, this is where mostly I based my App developed in Outsystems. Now let’s start!
Service Module
First, we need to create an Entity where we will store the generated Token and other data.
- SessionCode: This is where we store the Code that will be generated on the Web app that will be specific to each web client.
- DateAndTime: This is simply the Timestamp of the session code generated
- IsScanned: This will hold the flag that will determine if the user has already scanned the QR Code default value (False)
- EncryptedUserID: Will be used as storage for hashed user ID
- IsApprove: This will determine if the user has approved the request and for purging of data for DB Cleanup default value (False)
Now that the table is created next we create the CRUD wrapper needed. Then next we create the Web application.
Web Application
On the Web Application, I just used my existing personal project’s login page and modified it to have the QR Code generation. First I created a Web Block that will generate the QR Code and on this Block, I added an expiration to the QR code every 1 minute so that the user needs to regenerate the QR code for extra security.
Here the GenerateQRCode data action will be the main part of this block where it will generate all necessary data needed. You will see on the screenshot below I also created a Structure that has Details, TimeStamp, SessionCode, IPAddress, and Browser.
I divided the flow screenshot into three parts. 1st is Getting all data needed, 2nd is Removing and Saving the collected data to the database that we created, and 3rd is generating the QR Code.
1st we will get the IP Address of the User and then assign it to the structure next I used the GeneratePassword function with a length of 35 which will be Alphanumeric in theory there will be a very small chance that this code will have a duplicate. Each structure attribute will have a corresponding assign to it as seen in the screenshot above.
After collecting the data needed next, we will query the Table if there is an existing SessionCode saved, using the Local Variable TempSessionCode in the first load this will be empty the If condition IsApprove will go to a false branch since I set the default value to False.
The 2nd part is to save or delete the data from our Table created. As you can see in the image above I added an If widget, this is to determine if the same user will regenerate the QR Code and delete the previously generated record on the table, this is to minimize the table size but in return, this will flow will take longer to finish (This is open for comments you can have your implementation).
Then next if it does not exist the flow will just create a new record, after that, I will serialize the Data with the QRPush static entity.
3rd part is I encrypted the serialized data for an extra layer of security, I used the AES standard form CryptoAPI component (https://www.outsystems.com/forge/component-overview/437/cryptoapi) and then fed the encrypted value to the QRCoder component (https://www.outsystems.com/forge/component-overview/12980/qrcoder-qr-code-generation) and then generate the PNG also using the function from the component.
After the DataAction finishes fetching the data needed it will call the OnAfterFetch action where I added the Event to pass the Generated SessionCode to the Parent screen and will be used for verification. Then other Actions on the Block will be used for Countdown for Expiration, Regenerate QR Code action, etc.
Now on the Login screen of the Web Application, we will add the Block that we created and assign the proper handler that will receive the event from the block. Next will be a bit challenging part I also have difficulty in implementing it, so I only managed to use the very basic functionality of this plugin.
Since we need this to be in real-time when the user scans the code the Web app should be notified of the action taken from the mobile app. In this, I use this component (https://www.outsystems.com/forge/component-overview/10975/sse-push-event-hub) it’s a great component and gets the job done. I will not go through how to use the component you can check the documentation here (https://www.outsystems.com/forge/component-documentation/10975/sse-push-event-hub/0) or check the Demo application that the author created.
On the MessageReceived event handler.
This is where we are going to receive data processed on the Mobile application after scanning and approving the Request. As seen above we are going to Decrypt the “Message” input parameter from the Handler and then deserialize it to check each attribute needed for the flow, on the BrowserSession part remember that the block passes the SessionCode to the parent screen which is the Login Page in this we will be able to determine if the current request is still on the same browser session. If yes next is to check if the flow is on Scan only part and not approved by the Mobile app. If the user has scanned the QR Code, we will pass the value back to the QR code generation block to change the screen view from the QR Code to a check sign and stop the countdown for expiration. The screenshot below will provide insight into the login screen QR Code cycle.
The next flow will be if the User has approved the Request on his/her mobile app, the user will be logged in to the application. As seen on the screenshot for MessageReceived I used the Login function that accepts UserID only.
Mobile Application
Now let’s start building the Mobile app for scanning the QR Code. On this, I used a pre-created Mobile application from the App Template (DirectoryMobile) and added a Gear Icon that will navigate the user to the Scan button.
On the next screen I only just added a button (Scan) to launch the supported OutSystems plugin (https://www.outsystems.com/forge/component-overview/1403/barcode-plugin).
On the screen above upon clicking the button it will launch the Camera to scan the QR Code after which it will have a response of the activity.
The ScanQRCode is a wrapper of the plugin which will check the Cordova, availability of the plugin, and the scanning of the Code. After scanning.
The wrapper response will be checked and then go to the AuthenticationProcess action. I will divide this into two parts, the first is validating the request and updating the record, and the second is collecting data and notifying the web app.
1st we will decrypt the Value that the scanner received and deserialize it with the data type QRPush. Here we will query the item on the table using the SessionCode from the deserialized data then we assign the values to the Query output for update.
Then we will update the Record.
2nd part will be assigning data to the Temporary variable and notifying the Web application. This part is crucial for us to achieve the real-time update to the web app. As mentioned, before we used the SSE push event, in that component there is a function to notify the channel.
Note that I used the basic function of the component and based on my exploration you can use other functions for extra security and fit your needs.
Also, on this flow, the Temporary values that we assigned will be used on the Approval part of the application.
After the scanning and verification of the request if all is successful the app will display a popup that has the Details of the Request.
The user can Approve or Cancel the request. If the user approves the request. As shown on the flow below the IsApprove will be updated and we will add the Hashed User ID and then update the record.
Then we will again assign the data to the QRPush structure serialize and encrypt it and assign the encrypted value to the NotifyEvent function from the SSH push Event.
After which if success full validation the mobile app will prompt a successful message.
The web application login request will now be granted, and the user will be logged in to the web app.
Note that the web application is one of my personally developed apps this is a quiz app and questions are from the OS Website and others are situational.
~pipaw