Tutorial: Login with email & password

Step by stepAuthentication Login with email & password

[[service]] provides a classical Email/password authentication method easy to integrate into your applications. Credentials are securely stored and encrypted in the [[service]] back-end.

By default the Email/password authentication method is enabled on new [[service]] applications. If necessary, it can be disabled in the "authentication" tab of the [[console]].

[[service]] SDK exposes methods to create, authenticate and manage Email/password identities, letting the application developer have full control over the user interface.

Creation of Email/password identities

Each created Email/password identity also creates a [[service]] user account associated to this identity. In future versions, it will be possible to bind other identities (from any authentication method) to an existing account. Typically, the same end user will be allowed to authenticate either with one or more Email/password credentials or with a google or facebook account. Consequently, applications should manage their users always using their account uid, but never using their identity id (i.e. their email in case of Email/password authentication method).

To create a new Email/password identity (and therefore a new [[service]] user account) for a given application, use the following snippet [[snippet]]:

// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Create a new Email/password identity
ref.createUser({
  email: "macadamia@webcom.com",
  password: "nutbrittle"
}, function(error, identity) {
  if (error) {
    console.log("User identity not created:", error);
  } else {
    console.log("User identity created and bound to the new account uid:", identity.uid);
  }
});
// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Create a new Email/password identity
ref.createUser({
  email: "macadamia@webcom.com",
  password: "nutbrittle"
}).then(function(identity) {
  console.log("User identity created and bound to the new account uid:", identity.uid);
})
.catch(function(error) {
  console.log("User identity not created:", error);
});
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.createUser("macadamia@webcom.com", "nutbrittle", new OnAuth(){
  @Override
  public void onComplete(@Nullable AuthResponse response) {
    // User identity created and bound to a new account uid
    String uid = response.getUid();
  }
  @Override
  public void onError(WebcomError error) {
    // User identity not created
  }
});

The identity parameter received by the given callback is a JSON structure representing the created identity, with the following fields:

Field Type Description
provider String The authentication method associated to the newly created identity, here: "password".
providerUid String The identity ID, here the email address used to log in.
uid String The newly created user account ID, to which the identity is bound.
It is unique across all authentication methods.
createdAt Number The date (expressed in seconds since the Unix epoch) of creation of the identity.
providerProfile Object (optional) The profile data associated to the identity, which can be specified using the profile attribute within the credentials object passed as first argument of the createUser() function.

In case of error, the onError method is called with an object describing the root cause of the error. Otherwise, the onComplete method is called with an authResponse representing the just created (Email/password) identity.

The newly created identity is bound to a new user account. However it remains blocked for login as long as the end user doesn't confirm it (by clicking on the link emailed by [[service]]).

Confirmation of Email/password identities

A new Email/password identity is created in the unverified state and must be confirmed, that is switched to the verified state, before users can use it to log in. Actually, a message is sent to the specified email address when an identity is created, which contains a link to confirm it. The default message links to a generic page served by the [[service]] back-end.

In order to customize the user experience for confirming an identity, you can edit the message template in the "authentication" tab of the [[console]]. You can then include a link to a customized confirmation page from your application. In turn, this page must end in requesting the following HTTP REST [[service]] API:

curl -X PUT "[[baseUrl]]/auth/v2/<your-app>/password/confirm?token=<confirmation-token>"

Where:

  • <your-app> must be replaced with your application identifier. If your confirmation page is not application-specific, it can be passed to the confirmation page as a query-string using the %app% macro within the message template edited on the [[console]].
  • <confirmation-token> must be replaced with the token generated by the [[service]] back-end when the identity was created. It can be passed to the confirmation page as a query-string using the %token% macro within the message template edited on the [[console]].

If the final user doesn't receive the confirmation email for some reason (although it is seldom it may occur as the email dispatching infrastructures are not guaranteed 100% reliable), you can ask the [[service]] back-end to send a new confirmation email so that the user has a chance to finalize her/his email address verification:

// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Send a message to reset the password
ref.sendConfirmationEmail("macadamia@webcom.com", // the email for which confirmation email must be resent
  function(error) {
    if (error === null) {
    console.log("The confirmation email was sent successfully");
  } else {
    console.log("The confirmation email was not sent:", error);
  }
});
// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Send a message to reset the password
ref.sendConfirmationEmail("macadamia@webcom.com", // the email for which confirmation email must be resent
).then(function() {
  console.log("The confirmation email was sent successfully");
}).catch(function(error) {
  console.log("The confirmation email was not sent:", error);
});
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.sendConfirmationEmail("macadamia@webcom.com", new OnAuth(){
  @Override
  public void onComplete(@Nullable AuthResponse response) {
    // The confirmation email was sent successfully
  }
  @Override
  public void onError(WebcomError error) {
    //The confirmation email was not sent
  }
});

Login with Email/password identities

Once confirmed, an Email/password identity can be used to log in, using the following snippet [[snippet]]:

// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Log in
ref.authWithPassword({
  email    : "macadamia@webcom.com",
  password : "my-password"},
  function(error, auth) {
   if (error) {
     switch (error.code) {
       case "INVALID_CREDENTIALS":
         console.log("The email or password is incorrect.");
         break;
       case "PROVIDER_DISABLED":
         console.log("The Email/password method is disabled in the application. It must be enabled in the [[console]].");
         break;
       default:
         console.log("An unexpected error occurs, please retry and contact your administrator.", error);
     }
   } else {
     console.log("Authentication succeeded", auth);
   }
 }
);
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.authWithPassword("macadamia@webcom.com", "my-password", new OnAuth(){
  @Override
  public void onComplete(@Nullable AuthResponse authResponse) {
    // User account authenticated
    String token = authResponse.getToken();
  }
  @Override
  public void onError(WebcomError error) {
    // User account not authenticated
  }
});

The auth parameter received by the authentication callback function is a JSON structure representing the identity used to log in.

In addition to the generic fields, it includes the following ones:

Field Type Description
provider String Equals "password".
providerUid String The email address of the logged in user.
providerProfile Object (optional) The profile of the logged in user, when specified at creation with the createUser() method.

In case of error, the onError method is called with an object describing the root cause of the error. Otherwise, the onComplete method is called with an authResponse representing the identity used to log in.

Update of Email/password identities

Updating password

There are 2 cases to update the password of an email/password identity: either you know the currently associated password, or you don't know (or have forgotten) it. In the first case, simply use the changePassword() method [[snippet]]:

// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Update the password
ref.changePassword("chocolate@webcom.com", // email
  "pralinesandcaramel", // current password
  "midnightcookies", // new password
  function(error) {
    if (error === null) {
      console.log("Password changed successfully");
    } else {
      console.log("Error changing password:", error);
    }
  });
// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Update the password
ref.changePassword("chocolate@webcom.com", // email
  "pralinesandcaramel", // current password
  "midnightcookies" // new password
).then(function() {
  console.log("Password changed successfully");
}).catch(function(error) {
  console.log("Error changing password:", error);
});
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.changePassword("chocolate@webcom.com", "pralinesandcaramel", "midnightcookies", new OnAuth(){
  @Override
  public void onComplete(@Nullable AuthResponse response) {
    // Password changed successfully
  }
  @Override
  public void onError(WebcomError error) {
    // Error changing password
  }
});

In the second case, use the sendPasswordResetEmail() method [[snippet]]:

// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Send a message to reset the password
ref.sendPasswordResetEmail("macadamia@webcom.com", // the email for which the password must be reset
  function(error) {
    if (error === null) {
    console.log("The Reset password email was sent successfully");
  } else {
    console.log("The Reset password email was not sent:", error);
  }
});
// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Send a message to reset the password
ref.sendPasswordResetEmail("macadamia@webcom.com", // the email for which the password must be reset
).then(function() {
  console.log("The Reset password email was sent successfully");
}).catch(function(error) {
  console.log("The Reset password email was not sent:", error);
});
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.sendPasswordResetEmail("chocolate@webcom.com", new OnAuth(){
  @Override
  public void onComplete(@Nullable AuthResponse response) {
    // The Reset password email was sent successfully
  }
  @Override
  public void onError(WebcomError error) {
    //The Reset password email was not sent
  }
});

The [[service]] back-end then emails a message to the specified user, with a link to safely change her/his password without need of the current password. The default message links to a generic page served by the [[service]] back-end.

In order to customize the user experience for resetting an identity password, you can edit the message template in the "authentication" tab of the [[console]]. You can then include a link to a customized reset page from your application. In turn, this page must end in requesting the following HTTP REST [[service]] API:

curl -X PUT "[[baseUrl]]/auth/v2/<your-app>/password/update?token=<reset-token>"
     -H "Content-Type: application/x-www-form-urlencoded"
     -d "newPassword=<new-password>"

Where:

  • <your-app> must be replaced with your application identifier. If your password reset page is not application-specific, it can be passed to the password reset page as a query-string using the %app% macro within the message template edited on the [[console]].
  • <reset-token> must be replaced with the token generated by the [[service]] back-end when it sent the password reset message to the user. It can be passed to the reset page as a query-string using the %token% macro within the message template edited on the [[console]].
  • <new-password> must be replaced with the new password to associate to the user's email. It typically comes from a form displayed by the password reset page.
    Note: this parameter is part of an URL-encoded form data, therefore it has to be percent-encoded with UTF-8 encoding.
Updating profile

As mentioned above, when creating an email/password identity, a profile may be associated to it, which is specified as a JSON object. In order to update this profile, you can use the updateEmailPasswordProfile method. It requires that you are already authenticated with an email/password identity, it will then update the profile associated to this currently authenticated identity.

// Authenticate with an email/password identity...
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.authWithPassword({email: "macadamia@webcom.com", password: "my-password"}, function(error) {
    if (!error) {
        // ...and then update its profile
        ref.updateEmailPasswordProfile({age: 42, zipcode: 22300}, function(error) {
            if (error) {
                console.log("The update failed:", error);
            } else {
                console.log("The profile has been successfully updated");
            }
        });
    }
})
// Authenticate with an email/password identity...
let ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.authWithPassword({email: "macadamia@webcom.com", password: "my-password"})
    .then(() => {
        // ...and then update its profile
        ref.updateEmailPasswordProfile({age: 42, zipcode: 22300})
            .then(() => console.log("The profile has been successfully updated"));
        })
    .catch(error => console.log("The update failed:", error));
// Authenticate with an email/password identity...
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.authWithPassword("macadamia@webcom.com", "my-password", new OnAuth() {
    @Override
    public void onComplete(@Nullable AuthResponse response) {
        // ...and then update its profile
        ref.updateEmailPasswordProfile("age", 42, new OnAuth() {
            @Override
            public void onComplete(@Nullable AuthResponse response) {
                // profile updated!
            }
            @Override
            public void onError(WebcomError error) {
                ...
            }
        });
    }
    @Override
    public void onError(WebcomError error) {
        ...
    }
});

If no user is currently authenticated or if the currently authenticated user is not identified with an email/password identity, then the method will end in calling the specified callback with an error.

Deletion of Email/password identities

In order to delete an Email/password identity, you need the password associated to this identity and call the following method [[snippet]]:

// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Delete the identity
ref.removeUser("macadamia@webcom.com", // email of the identity to delete
  "nutbrittle", // associated password
  function(error) {
    if (error === null) {
      console.log("Identity removed");
    } else {
      console.log("Identity not removed:", error);
    }
});
// Create a connection to the back-end
var ref = new Webcom("[[baseUrl]]/base/<your-app>");
// Delete the identity
ref.removeUser("macadamia@webcom.com", // email of the identity to delete
  "nutbrittle", // associated password
).then(function() {
  console.log("Identity removed");
}).catch(function(error) {
  console.log("Identity not removed:", error);
});
Webcom ref = new Webcom("[[baseUrl]]/base/<your-app>");
ref.removeUser("macadamia@webcom.com", "nutbrittle", new OnAuth(){
  @Override
  public void onComplete(@Nullable AuthResponse response) {
    // User account removed
  }
  @Override
  public void onError(WebcomError error) {
    // User Account not removed
  }
});

Warning: deleting an identity doesn't delete the [[service]] account to which it is bound, because other identities may still be bound to this account.