November 19, 2023

Web3 authentication in embeddable javascript widgets

Tricky parts of implementation of Web3Auth.io SDK

Recently I’ve been working on a web3 project and had to solve few pretty complex challenges. And wanted to share my experince. So the project is an embedded javascript widget which could be added to any website. Widget provides user authorization via web3auth sdk, including oauth2 authorization using social networks.

Web3 Auth Widget Preview

Web3 Auth Challenges

As this is embeddabe widget, the source code of the widget should be as lightweight as possible. Also to avoid any possible conficts with other scripts used on the website, we’re pretty limited in 3rd-party libraries we can use. However we need to use several web3auth package (for example: @web3auth/base and @web3auth/openlogin-adapter).

Also, having 3rd-party libraries in embeddable script increases chances to some unexpected behaviour, as show on the example below:

JS Minification Error

After minification, one function name has been renamed to $() which caused conflicts with jQuery and other scripts.

To solve this issue, we can split our widget into 2 separate parts: embedded widget itself and authentication modal window which will be opened in the iframe.

Having authentication window in the iframe will also solve another issue with web3 social login via oauth2 protocol. OAuth protocol requires us to set us a callback url, to which the authentication code will be sent during authentication process, for example: https://example.com/?widget_auth=success. And as we would like to allow our widget to be embeddable to unlimited number of websites, we can’t set callback urls for all these websites in bulk. As our authentication window will be opened in an iframe - it always has a fixed callback url. And then we just need to pass authentication information back to the parent window (where our embeddable widget is embedded).

Web3 Auth Diagram

To send the information from the iframe back to our main widget, we can use window.parent.postMessage function in the authentication window and listen for the message event in our main widget.

It’s almost done, however it seems like our athentication window does not work in Safari on iOS and other browsers on mobile devices. This is because Safari is blocking any modal windows opened by javascript. To solve this issue, we need to make a few changes to our code:

If the user is on mobile, we need to call window.open function to open the same authentication window in a new tab and pass the id of the choosen social login, and on window load we need to manually call web3auth.init() function. This way the authentication window will be opened in a new tab, then we can pass the auth code back to the iframe in opened in previous tab using window.opener.postMessage function, and then - send the data from the iframe back to our main widget.

And that’s it! As a result, we have super lightweight embeddable main widget, written on vanilla js without any 3rd-party libraries and we have highly customizable authentication script, which is running in iframe, where we can use any 3rd-party libraries we need, without having to worry about potentical conflicts on the websites which embedded our widget.

© 2023 [maxico.dev] — All rights reserved.