How to authenticate a user when both offline and online in Angular?

I am developing an offline first angular app using Pouch DB and Couch DB . The end user is a desktop user who wants to use the app even when not connected to the internet.

I am using Pouch DB for local database and Couch DB for remote database.

One of the difficulties in developing this application, is how to authenticate the users when they are both offline and online?

I adopted this algorithm:

Preconditions:

1)User should be connected to the internet during the first login .

2) User credentials are already available on remote server (Couch DB ) and the password is encrypted (I have used crypto-js for encryption)

STEP 1:

  • Capture user name and password entered using Angular Forms.

STEP 2:

  • Using the user name entered , fetch the user details from remote couch db. This can be done through Pouch DB sync API.
    • ( For every user use a seperate database in the remote server . Fetch this database. Only the user name and password will be present in this db. Creating one database per user is fine in NoSQL database though will be a performance hit in relational databases. I had created database for each user in the format ‘userdetails_username‘. So if user had entered the name ‘john’ the database “userdetails_john” would be downloaded and local Pouch DB would be updated )

Below is the code to sync local Pouch DB with remote Pouch DB ( I had installed Couch DB in my local and used that as remote)

 syncDBData(dbname) {

    var database = new PouchDB(dbname + this.username);

    var remotedatabase = new PouchDB('http://username:password@localhost:5984/' + dbname + this.username);

    let options = {
      live: true,
      retry: true,
      continuous: true
    };

    console.log("Replication starts");
    database.replicate.from(remotedatabase).on('complete', function () {
      console.log("Replication done one way - from remote");
    }).on('error', function (err) {

      console.log("error occured here " + err);
    });
}

STEP 3:

  • Decrypt the password just stored in the local db and compare it with the password entered by the user . Below is the code to check the credentials
import * as Cryptojs from 'crypto-js'
....
...
  

 async  checkCredentials(username, password) {

    console.log("checking credentials");

    this.syncDBData("userdetails");

    console.log(username)
    console.log(password)

    let result = await this.userdb.find(

      {
        selector: {
          username: username

        }
      }, function (res) {

        console.log(res)
      }
    );

    console.log(result);


    if (result.docs[0].username === username) {

      var encryptionKey = "secretKey";

      var passwordfromDB = Cryptojs.AES.decrypt(result.docs[0].password, encryptionKey).toString(Cryptojs.enc.Utf8);

      console.log(password);
      console.log(passwordfromDB);


      if (password === passwordfromDB) {
        console.log("Yes it is true")

        this.isAuthenticated = true;
        return true;
      } else {

        return false;
      }
    }

    return false;

  }

Notice the line :

   var passwordfromDB = Cryptojs.AES.decrypt(result.docs[0].password, encryptionKey).toString(Cryptojs.enc.Utf8);

This is the code to decrypt the password from the local database and compare with the password entered by the user.

I have used crypto-js for encryption and decryption .

It can be installed using the following command :

npm install crypto-js

If they match , login the user .

That’s it.

The user needs to be connected to the internet only while logging for the first time . After that the credentials will be stored in the browser Indexed DB and the code will be looking for them there.

I have skipped the registration process here. That will be done only online and the credentials will be stored on the remote Couch DB server.

I loved inventing this recipe.

Hope it helps you too!


Posted

in

, ,

by

Comments

Leave a Reply

Discover more from The Full Stack Developer

Subscribe now to keep reading and get access to the full archive.

Continue reading