Users

The content in this guide refers to the newly released version 3 of the library. You can still access the version 1.x guides here.

Version 1.x is now deprecated. We will continue to support 1.x through March 31, 2017 (End of Support - EOS). If you are currently using 1.x in your apps, you will need to upgrade your apps to 3.x before the EOS date. We have created a migration guide to help you.

User management is central to any application and central to Kinvey's backend-as-a-service.

The user management API has methods for handling typical user actions such as signup, login and logout. Using the API is as simple as calling each of those methods from the respective form and button in your app. An active user provides context for each interaction with your backend, ensuring that security is enforced and unauthorized access is disallowed. By default, a user's data is readable but not writable by other users.

A user object and its properties such as first name, last name and email are represented in the backend as an entity, and as such, most of the entity methods such as fetch and save apply.

Active User

The library has a concept of an active user which represents the person using your app. There can only be one active user at a time. All backend API calls are made with the credentials of the active user, enforcing the corresponding access control.

The active user can be obtained by calling Kinvey.User.getActiveUser(). Note that the resolved user may not necessarily reflect the latest user data on Kinvey. To refresh the active user, call user.me.

To use the code snippet below you will need to include your own promise library.

var activeUser = Kinvey.User.getActiveUser();
var promise = Promise.resolve(activeUser);

if (activeUser !== null) {
  promise = activeUser.me();
}

promise
  .then(function(activeUser) {
    // ...
  })
  .catch(function(error) {
    // ...
  });

Explicit vs. Implicit

There are two ways to set the active user in the library:

  • An explicitly set active user is one that your application will log in using a regular username and password on a login form, or via a social login through Facebook, Google, Twitter, LinkedIn.
  • An implicitly set active user is created by the library. This action happens upon the first login that the app makes from a device. The username and password of the implicit user are randomly generated.

Apps that have no explicit notion of user registration and identity, like mobile single-player games, can simply utilize the implicit login without any credentials.

For all other practical purposes the implicit user is the same as any other user; the complete user entity is cached locally, it can have custom attributes and it can be a destination for push notifications. Since an implicit login contains no credentials, it is lost upon uninstalling the application.

The following diagram shows how the flow differs for each way to set the active user:

Active User State

User class

The library represents users by a User class.

var user = new Kinvey.User({
  _id: 'user-id',
  _acl: { /* ACL */ },
  _kmd: { /* Metadata */ },
  email: 'email'
});

The following user fields have specific semantics in the backend:

You can add additional data on the user object using the data property. For example:

var user = new Kinvey.User();
user.data.customProp = 'foo';

You can retrieve the data of a user by accessing the data property.

var user = new Kinvey.User();
var userData = user.data;

Saving the User

Once the user object is modified, for those changes to make it to the server, it needs to be saved.

// Update the active users’ age.
var promise = Kinvey.User.update({
  "age": 21
});
promise = promise.then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

Authentication

When a user first installs and runs your app, a login context must be established. For new users, this is done through signup. For an existing user, this can be accomplished with login.

The methods used for login and signup are implemented as static methods on the User class. An active user is set on the Kinvey client only after a login attempt is successful. Once there is an active user, operations can be performed on the User instance.

Signup

Signup creates a new user in Kinvey. If the username does not already exist in your app backend, a new user will be created. The newly created user is automatically logged in as the active user.

If the user already exists, signup will result in an error.

var user = new Kinvey.User();
var promise = user.signup({
  username: 'username',
  password: 'password'
}).then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

If your app requires email verification, please store the user where it can be retrieved sometime later by your app to complete the email verification process. We recommend storing this in Local Storage on the browser.

var user = new Kinvey.User();
var promise = user.signup({
  username: 'username',
  password: 'password'
}).then(function onSuccess (user) {
  LocalStorage.setItem('newUser', JSON.stringify(user.toJSON()));
  return user;
}).then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

Sign up with Attributes

Optionally, when you sign up a new user, you can add a dictionary of attributes to be saved on the user at creation time.

Autogenerated Users

Apps that need to access data without requiring the user to log in can request automatically generated user. Autogenerated users are given a unique random username and password in Kinvey. On successful creation, the newly autogenerated user is set as the active user in the library.

var promise = Kinvey.User.signup().then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

A user token is required to access any data, even if that data is shared or public. If you want to access data without requiring login or account creation up-front, we suggest the following workflow.

  1. Use signup to create an autogenerated user. Use this user to access and create data on the backend.
  2. When the app/user is ready to add personal information, update the user object's username and other properties.
  3. Save the user object.
  4. Before returning control flow to the app, reset the password.

Login

For existing users, the app needs to estabish a login session before accessing data. Once a user logs in, the user context is cached on the device and subequent uses of the app do not require another call to login.

var promise = Kinvey.User.login('username', 'password').then(function onSuccess(user) {
  ...
}).catch(function onError(error) {
  ...
});

Alternatively, you can pass in an object containing the username and password.

var promise = Kinvey.User.login({
  username: 'username',
  password: 'password'
}).then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

Upon authentication, the response holds the user object.

Login is needed when a user exists in the app backend but has not been established in the application session. Common scenarios when this is necessary:

  • The application launches and an active user is not yet established
  • The application is reinstalled on the same or a new device for a user who already has an account established on the back-end
  • The user has logged out and the application needs to make more calls to Kinvey

Once the user logs in successfully, the library sets the active user and caches the user's authentication tokens for subsequent use.

To log in using a social identity provider, please to to the Social Identities section of the guide.

Logout

Logging out clears the active user and removes all cached tokens and data for the active user. This method has no effect if there is no active user.

var promise = Kinvey.User.logout();
promsie = promise.then(function onSuccess() {
  // ...
}).catch(function onError(error) {
  // ...
});

If your app needs to persist any attributes on the user, remember to save the user before logout. Logging out will clear any changes made since the last save.

A logout destroys the session’s associated auth token, such that subsequent attempts to re-use that token will yield a 401 Unauthorized (error) response.

When using a third-party Single Sign-On (SSO) identity provider (such as Ping Identity), the app’s logout action will destroy active session auth tokens within the Kinvey app, but SSO tokens may persist on third-party provider sites. Logout does not terminate tokens stored at third-party SSO websites using SAML or OAuth. Cookies that maintain these sessions may enable a logged out user to reopen a session and obtain a new session auth token. For instance, using Ping Identity with SAML-Redirect, the user will remain authenticated on Ping Identity website after logging out from the associated Kinvey application. This would enable a user to login to their Kinvey app after being logged out, i.e. if they remain logged in to Ping Identity.

User Lifecycle Management

You only need to remember the user if your app is explicitly setting the active user as explained in the active user section.

Once the application process is restarted, your app re-establishes the user context automatically and retrieves details about the user. At any time, you can refresh the metadata from the server by calling the Me method. This method requests an up-to-date copy of all user attributes from the Kinvey server.

TODO

Email Verification

Building email verification into your app ensures that your users provide you with correct and valid email addresses that they own during sign-up.

Configuration

The Console exposes several options that control how email verification is handled for your app. These options can be reached by navigating to the Users section and opening the Settings panel. The following settings are available:

  • Enforce email verification: by default, new apps do not enforce email verification. This means that while your users can go through the email verification process, any user can log into your app -- regardless of whether or not their email address is verified. In order to restrict access only to those users who have successfully verified their email addresses, enable the Enforce email verification option. Note that when this option is enabled, you will not be able to create a new user that does not have an email address.

    • Always allow access to users created before date: this option will become available when you turn on Enforce email verification. If enabled, any users created before the date you specify will be able to log into your app regardless of whether or not their email is verified. This option is intended to support apps with an existing user base in which users were not previously required to verify their email. The option will allow these existing users to log in, but require email verification from all new users created after the specified date.
  • Automatically send verification email: if this option is enabled, a verification email will automatically be sent when users are created, or when they change their email address. If this option is not enabled, you will need to manually initiate the email verification process (as described below) for each user in order to verify their email address.

Workflow

To request email verification, the user must have a valid email set in the email attribute. The following example shows how to send a verification email to the user.

To request email verification, start by retrieving the information for the user you stored after they successfully signed up. Call verifyEmail with the username that was stored. The user must have a valid e-mail address set in the email attribute.

var userData = JSON.parse(LocalStorage.getItem('newUser'));
var user = new Kinvey.User(userData);
var promise = user.verifyEmail();
promise.then(function onSuccess() {
  // ...
}).catch(function onError(error) {
  // ...
});

The user must have a valid e-mail address set in the email attribute.

This request will start the email verification process, and will cause an email to be sent to the user requesting they confirm their email address by clicking on a link included in the email body. The link is served by Kinvey and is valid for five days from the time of the email. The email address for a user must be stored in a property named email in the user object.

Email Verification Request

The workflow completes when the user opens and clicks on the link in the email, thus confirming their email address. A final email is then sent to the user letting them know that their email address was successfully confirmed.

Email Verification Completed

You can check the status of the email verification for a user.

You can check if an email is verified for a particular user by calling the isEmailVerified method on the user. Please note that you have to refresh the active user first using user.me if you are directly obtaining the status after calling user.verifyEmail.

var verified = user.isEmailVerified();

You can get the status of the email verification process by looking at the metadata of the user.

var status = user.metadata.emailVerification;

The verification workflow exposes the following states for user status:

  • sent: an email was sent in response to a verification initiate request
  • resent: multiple emails were sent in response to verification initiate requests
  • delivered: the email was successfully delivered to the user's mailbox (as reported by the remote server)
  • bounce: an email previously sent was bounced back by the remote server and couldn't be delivered
  • deferred: the mail system ran into transient problems delivering the email and deferred further attempts
  • dropped: the mail system dropped the email because of errors
  • confirmed: the user opened the email and clicked on the link enclosed in the email.

Each time the status changes, the time of change is recorded as "lastStateChangeAt".

Customization of verification emails

You have the option of customizing the contents and appearance of the emails that are sent to your app users. To customize these emails, navigate to the Branding section of the console. You'll see each of the user flows that involve emails or web pages from Kinvey, with the ability to modify each. You may modify the from and reply-to email fields, as well as the subjects and bodies of both the first email and the confirmation email.

Email Verification Customization

The From Address and Reply-To Address can be in the form: Display Name <account@server.com> or just account@server.com. Be aware that even if you change these fields, the email will still be sent from support@kinvey.com, and this might cause the message to be flagged by some mail clients.

The Subject and Email fields support mustache templates (tags within double curly-brackets). The email field supports HTML bodies, but a plain-text version will be generated and sent along in the message as well.

The available tags vary by email type. The available tags are:

Verification Email:

  • appname - the application name
  • fname - the user's first name, as specified by the first_name field in the user collection.
  • username - the user's username, as specified by the username field in the user collection. The first two lines of the default template are a switch that uses first name if available, and username if one is not.
  • url - the link the user needs to click to verify the email and show the verification page
  • expirationTimeDays - how many days the link is valid for (from generation time)
  • expirationDate - the exact date the link will expire

Congratulations Email:

  • appname - the application name
  • fname - the user's first name, as specified by the first_name field in the user collection.
  • username - the user's username, as specified by the username field in the user collection. The first two lines of the default template are a switch that uses first name if available, and username if one is not.
  • lastChangedAt - the time the user submitted a new password

Customization of successful verification page

You have the option of customizing the HTML "success" page that is displayed when a used has successfully verified their email by clicking the link sent to them.

Email Verification Success Page

The page supports mustache templates (tags within double curly-brackets). The available tags are:

  • appname - the application name
  • fname - the user's first name, as specified by the first_name field in the user collection
  • username - the user's username, as specified by the username field in the user collection
  • lastChangedAt - the time the user submitted a new password

Password Reset

Users can request that our system send them an email with a temporary password reset link. This link will open a web page where they can set a new password. The user must have a valid email set in the email attribute.

var promise = Kinvey.User.resetPassword('<username>');
promise = promise.then(function onSuccess() {
  // ...
}).catch(function onError(error) {
  // ...
});

This request will send an email containing a secure time-bound link to the email address on record for the user. The link is served by Kinvey and is valid for twenty minutes from the time of the email. A link can be used for only one reset. Submitting the form will update the password for the user. The user will also receive a confirmation email when they complete the password reset.

Requesting a password reset will invalidate any active session tokens for the user and require a new login on any device using the app.

Password Reset

Until the password reset is complete, the old password remains active and valid. This allows the user to ignore the request if he remembers the old password. If too much time has passed, the email link will no longer be valid, and the user will have to initiate a new password reset.

Password Reset Email Customization

You have the option of customizing how the email is presented to your app users by specifying the from and reply-to email fields as well as the subjects and bodies of the first email and the congratulations email.

Email Verification Customization

The From Address and Reply-To Address can be in the form: Display Name <account@server.com> or just account@server.com. Be aware that even if you change these fields will still be sent from support@kinvey.com, and this might cause the message to be flagged by some mail clients.

The Subject and Email fields support mustache templates (tags within double curly-brackets). The email field supports HTML bodies, but a plain-text version will be generated and sent along in the message as well.

The available tags vary by email type. The available tags are:

Reset Email:

  • appname - the application name
  • fname - the user's first name, as specified by the first_name field in the user collection.
  • username - the user's username, as specified by the username field in the user collection. The first two lines of the default template are a switch that uses first name if available, and username if one is not.
  • reseturl - the link the user needs to click to go to the reset password page
  • expirationTimeMins - how many minutes the link is valid for (from generation time)
  • expirationDate - the exact date the link will expire

Congratulations Email:

  • appname - the application name
  • fname - the user's first name, as specified by the first_name field in the user collection.
  • username - the user's username, as specified by the username field in the user collection. The first two lines of the default template are a switch that uses first name if available, and username if one is not.
  • lastChangedAt - the time the user submitted a new password

Using a Custom Password Reset Page

Rather than using the default password reset page hosted on Kinvey, you may optionally host a password reset page on your server. A link to this page will be included in the email sent to your app's users when they reset their password. Typically, you would select this option if you want your users to see a link pointing to your domain rather than to kinvey.com, and/or brand the page in any way you like to better fit your app's visual style.

Background and Process

In order to understand where your custom page fits in, it's helpful to understand the general password reset process:

  1. A user attempts to reset their password. Your app makes a request to the password reset endpoint, either directly or via a client library.

  2. Kinvey sends an email to the user, with a link to baas.kinvey.com/rpc/:kid/:usernameOrEmail/user-password-reset-process (including parameters such as time, nonce and sig).

  3. When the user clicks the link, your app's password reset page is dynamically generated by Kinvey's servers and displayed to the user.

  4. When the user submits the form on the password reset page, their browser requests baas.kinvey.com/rpc/:kid/:usernameOrEmail/user-password-reset-complete (again, with some additional parameters), which resets their password, and displays a confirmation page.

The custom password reset page that you will host will essentially replace the third step described above. A link to your page will appear in the email sent to the user, and your page will then be responsible for parsing the required parameters from the email's link and passing them, along with the new password, onto the Kinvey endpoint mentioned in step 3.

Template

The first step in creating your custom password reset page is downloading our template:

Download Template

The template contains a very simple password reset page that is modeled after our own. It contains a few lines of JavaScript code which parse the parameters from incoming URL, as well as a form allowing the user to input his new password. When the submit button is clicked, the form will send the required parameters to the Kinvey endpoint mentioned in step 3 above.

You are free to customize this form as you wish. Be aware that the Kinvey endpoint that completes the password reset process expects the data to be presented in a certain format, and you should be careful when modifying the JavaScript code or the form elements. After you have made your changes, always make sure that the newly modified page still works as expected by trying to reset a user's password through the Kinvey Console.

When you have finished customizing your password reset page, upload it to your server and make note of the URL. You will need to enter the page's URL in the next step.

Console Configuration

Once you have customized your page and uploaded it to your server, it is time to configure Kinvey so that it uses your page instead of the default one. To do so, open the Kinvey Console, navigate to the Users section, and open the Setting panel.

Select the Password Reset tab, and enter the URL for your custom page in the input field, and press the Save Changes button. This will complete the setup process, and your new page will now be used for all future password reset requests from your app.

It is highly recommended that you now test the password reset process in order to make sure that the changes you have made to the page are compatible.

Change Password

If the user is already logged in but wants to change the password, simply set a new password property on the user object and save the user.

var promise = new Kinvey.User.update({
  password: 'new-password'
});
promise = promise.then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

Forgot Username

If the user has forgotten the username to sign in, you can have Kinvey send an email with the username to the address set in the user's email field.

var promise = Kinvey.User.forgotUsername('<email>');
promise = promise.then(function onSuccess() {
  // ...
}).catch(function onError(error) {
  // ...
});

Removing the User from the System

The snippet below shows how to permanently remove the user without an ability to re-enable.

var promise = Kinvey.UserStore.removeById('user-id', {
  hard: true
});
promise.then(function onSuccess() {
  // ...
}).catch(function onError(error) {
  // ...
});

You can also suspend a user, rather than deleting them permanently. A suspended user can be reactivated through the Kinvey Console.

var promise = Kinvey.UserStore.removeById('user-id');
promise.then(function onSuccess() {
  // ...
}).catch(function onError(error) {
  // ...
});

Re-enabling disabled users can only be done using the Master Secret. Therefore, this should never be done through your client-side app.

Deleting the user removes the user but keeps their data intact in the backend. This has the effect of not allowing a username to be reused once deleted. If you need to free up a deleted username, contact support@kinvey.com.

Global User Administration

Username Existence Check

You can check whether a specific username already exists within your app.

var promise = Kinvey.User.exists('usernameToCheck');
promise.then(function onSuccess(exists) {
  // ...
}).catch(function onError(error) {
  // ...
});

Kinvey will respond with a boolean true if the username is already in use, or false if it is available for a new user.

User Discovery

Apps often need to share data between users or provide contact information of other users of the app. In such cases, user discovery is a way for your app to retrieve users from the user collection through a query or by fetching all.

When fetching other user objects, be aware that these user objects are immutable. The Kinvey backend will not allow one authenticated user to change another user's attributes. Also note that the permissions set on the User collection determine whether users can see other users in the app.

You can lookup users based on the following criteria:

  • username
  • last_name
  • first_name
  • email
  • _socialidentity.facebook.id
var query = new Kinvey.Query();
query.equalTo('firstName', 'John');
var promise = Kinvey.User.find(query, {
  discover: true
});
promise.then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

When setting multiple fields in the UserDiscovery object, be aware that the results must match all the set criteria in order to be returned. In the above example, only results where the first name is "James" and the email is "james.bond@mi6.com" will be returned. If only the first name is set to "James", more results matching this criteria may be returned.

Login with Social Identities

You can use social identities to simplify user management in your app. By offering options for your users to login using their Facebook, Twitter, Google+, or LinkedIn accounts, you eliminate a source of friction by not requiring that users create app specific usernames and passwords just for your app.

With Kinvey you can register multiple social identities against the same Kinvey user and switch between them as needed. This allows you to offer multiple login options (e.g.: Login with Facebook and Login with Twitter) in your app.

To use Social Identities in your app, make sure to follow the How to Implement Safe Sign-In via OAuth tutorial as it includes the critical steps required to enable the functionality described below.

To link a social identity to a user, use the connect method. The connect method will perform the entire authentication flow. This includes opening any external pop-ups, and verifying obtained access tokens. The method will attempt to login an existing user with the obtained tokens. If such a user does not exist, it creates a new user and associates the social identity with that user.

Alternatively, if you already have possession of the required tokens, you can use the connectIdentity() function to login directly:

The connectWithIdentity() function has been deprecated.

var promise = Kinvey.User.connectIdentity(Kinvey.SocialIdentity.Facebook, '<access_token>');
promise = promise.then(function onSuccess(user) {
  // ...
}).catch(function onError(error) {
  // ...
});

Facebook

To link a Facebook identity to a user, you’ll need to obtain an access_token and expires_in. You can obtain these by integrating Facebook Login in your app.

var promise = Kinvey.User.loginWithProvider('facebook', {
    access_token : 'facebook-access-token',
    expires_in   : 'expires_in'
}, {
    success: function(response) {
        ...
    }
});

Kinvey will validate credentials with Facebook and retrieve the corresponding user’s identity from Facebook. Use the login method to login an existing user by its Facebook identity.

var promise = Kinvey.User.loginWithProvider('facebook', {
    access_token : 'facebook-access-token',
    expires_in   : 'expires_in'
}, {
    success: function(response) {
        ...
    }
});

To unlink a Facebook identity from a user, set the facebook property to null and update the user.

var user = Kinvey.getActiveUser();
user._socialIdentity.facebook = null;// Unlink.
var promise = Kinvey.User.update(user, {
    success: function(response) {
        ...
    }
});

Google

To link a Google+ identity to a user, you’ll need to obtain an access_token and expires_in. You can obtain these by integrating the Google OAuth2.0 workflow in your app.

var promise = Kinvey.User.signupWithProvider('google', {
    access_token : 'google-access-token',
    expires_in   : 'expires_in'
}, {
    success: function(response) {
        ...
    }
});

Kinvey will validate credentials with Google+ and retrieve the corresponding user’s identity from Google+. Use the login method to login an existing user by its Google+ identity.

var promise = Kinvey.User.loginWithProvider('google', {
    access_token : 'google-access-token',
    expires_in   : 'expires_in'
}, {
    success: function(response) {
        ...
    }
});

To unlink a Google+ identity from a user, set the google property to null and update the user.

var user = Kinvey.getActiveUser();
user._socialIdentity.google = null;// Unlink.
var promise = Kinvey.User.update(user, {
    success: function(response) {
        ...
    }
});
Got a question?