📜 ⬆️ ⬇️

Two aspects of “decentralized” one-page applications

In the article we will try to describe two completely unrelated aspects of decentralized one-page applications. This connection of two users and saving passwords in a one-page application using a browser.

Information about the technology used WebRTC - webrtc.org . In the browser, the whole point of communication is tied to this technology, or rather to the WebRTC API which is available to the Front-end developer.

One of the goals was to create a decentralized chat, chat without using a server. However, the server was just necessary to implement the following features:


Making a connection


Consider in detail the connection scheme for two users. To do this, we highlight the main steps in the usual connection scheme of Client A and Client B:
')
  1. Client A is the initiator of the connection and generates an offer (Offer), that is, an sdp offer that contains all the available codecs on which the client can communicate and other information. Client A sends his sdp offer to Client B.

  2. Client B accepts the sdp offer and generates the answer (Answer), that is, the sdp response. At this stage Client B generates all available codecs and selects those that are available to both clients, adds its information and sends it to Client A.

  3. Client A receives an sdp-response from Client B. Further, Client A already communicates directly with Client B on the basis of the received reply and the information in it. After that between them formed RTCDataChannel - data exchange channel.

The highlighted words in three cases just show why you need a server at the initial stage of the connection. For data exchange through the server.

In our chat, both clients can simultaneously initiate a connection, but as a result we still want to get only one RTCDataChannel connection between two clients. The signal server can, of course, tell which client to initiate - and which one to wait for the offer. But to minimize the connection error, we launch a mechanism in which each of the clients is initiating and receiving at the same time. As a result, we leave that client-client connection, which is formed faster. Consider in more detail this aspect.

Below is a diagram of the connection of two initiating / receiving clients.


  1. At the same time, both clients receive an alert via a web socket connection that they are in the same chat. Client A and Client B initiate the connection - each generates its own sdp-offer and sends it to the server.

  2. The server, in turn, sends the received proposals to the addressees (the proposal from Client A sends to Client B, the proposal from Client B sends to Client A).

  3. Each client after receiving the sdp offer generates an sdp response to it. Both clients send their sdp responses to the server.

  4. The server, in turn, sends the received sdp-answers to their addressees (the answer from Client A is sent to Client B, the answer from Client B is sent to Client A).

  5. Each client receives an sdp response and accepts it. The important condition is that each client has the logic that with each other client there can be no more than one connection. Accordingly, if Client B has an open RTCDataChannel with Client A, then he does not create a new RTCDataChannel with him, one might say, everything else is simply ignored. Thus, the connection that is created faster and wins.

Thus, when two clients initiate a connection, there will be only one RTCDataChannel between them, not two.

User Registration and Browser History


When working with the application, each user goes through the following steps:

  1. Registration - for each new user.
  2. Authorization - for each previously registered user.
  3. Directly work with chat.

For this purpose, the application provided three pages, each of which is intended for the corresponding stage (site structure):


But pages are generated on the client, and HistoryAPI is used to navigate between them. An important point for the ease of use of the application is the preservation of user authentication data in the browser (password), using the default behavior of the browser.

In our case, the entered user data should be offered to save for the login form when changing url from "/ login" to "/ chat", and when changing "/ login" to "/ register" should not be offered. In practice, this proved impossible to implement. Saving was offered when switching from "/ login" to "/ register" and from "/ register" to "/ login". Thus, the task was to cancel the saving of data in the browser for certain cases.

To address this issue, various methods have been used, which are presented below.

Autocomplete for form


To disable autocomplete on the registration page, set the 'autocomplete' attribute for the entire form with the value 'off'.

The markup for this option:

<form autocomplete="off" data-role="loginForm"> <label> :</label> <input type="text" name="userName"> <label> :</label> <input type="password" name="userPassword"> <button type="submit"></button> </form> 

Link to this solution stackoverflow.com/a/468295 .

Autofill for specific fields


We tried to disable autocomplete on the registration page by setting the 'autocomplete' attribute with a value of 'off' for the input fields, that is, the user name and password.

The markup for this option:

 <form data-role="loginForm"> <label> :</label> <input type="text" name="userName" autocomplete="off"> <label> :</label> <input type="password" name="userPassword" autocomplete="off"> <button type="submit"></button> </form> 

The previous link discusses this option.

Hiding Fields


This option involves adding a hidden div to the markup, which includes the username and password fields that will always remain empty. The markup for this option:

 <form data-role="loginForm"> <div style={{display:'none'}}> <input type="text" /> <input type="password" /> </div> <label> :</label> <input type="text" name="userName" autocomplete="off"> <label> :</label> <input type="password" name="userPassword" autocomplete="off"> <button type="submit"></button> </form> 

Link to this solution stackoverflow.com/a/25111774 . A similar solution is proposed in this source.

Field zeroing with submit


In this variant we resort to the help of js. When a user clicks the “Login” button on the submit event, we reset the name and password fields.

Program Code:

  handleSubmit: function(event) { this.loginForm = document.querySelector('[data-role="loginForm"]'); event.preventDefault(); this.loginForm.elements.userName.value = ''; this.loginForm.elements.userPassword.value = ''; } 

Data reset was performed both immediately after the click, and after a certain time interval (SetTimeout ()).

Program transition through HistoryAPI


The last option is to create a new button in the form that would serve as the submit button.

The markup of this option:

 <form data-role="loginForm"> <label> :</label> <input type="text" name="userName" autocomplete="off"> <label> :</label> <input type="password" name="userPassword" autocomplete="off"> <button type="button" data-action="submit" onclick="handleClick"></button> </form> 

Program Code:

 handleClick(event) { if (event.target.dataset.action === 'submit'){ history.pushState({foo: 'bar'}, 'Title', '/chat') } } 

All of the above methods did not allow one password to save the password, and the other does not save. You could either always save or never save.

Hence, of course, it’s about painful time, that it’s time for one-page applications to make a JS API for the browser about saving a password:

 window.navigator.promtPasswordSave() 

Something like this would be great.

Currently, as a solution to the issue in question, the structure of the site has been changed to the following:


Where the / account page has two internal states, login and register, depending on this state, we generate one or another markup. Only in this way we were able to solve the problem with controlled saving of the password in the browser.

SPACHAT (Single Page Application Chat) is a web messaging application between clients using WebRTC technology, which we implement. You can see the implemented application or just chat on spachat.net .

The code itself is directly available at github.com/volodalexey/spachat .

Source: https://habr.com/ru/post/316556/


All Articles