Users

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 initializing an instance of the Kinvey client, and then calling mKinveyClient.user().

After authenticating a user, the library automatically caches the user's name and a current authorization token in a saved credential store. The credential store is private to the application process that created it and is removed when the application is uninstalled.

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 log in form, or via a social log in 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 code snippet shows an implicit user login.

import com.kinvey.nativejava.Client;

...

final Client mKinveyClient = new Client.Builder(appKey, appSecret).build();
try{
    User currentUsers = mKinveyClient.user().loginBlocking().execute();
} catch (IOException e) {
    System.out.println("Couldn't login -> " + e);
}

User class

The User class is used to represent a user. It extends GenericJson and so metadata fields are automatically available as part of the standard persistence flow. You may explicitly save attributes on the active user object in the same manner that you would save properties on any AppData entity. This is done with the User.put(String key) and User.get(String key) methods.

The following fields have specific semantics in the backend:

Saving the User

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

mKinveyClient.user().put("fav_food", "bacon");
try{
    User result = mKinveyClient.user().updateBlocking().execute();
} catch (IOException e) {
    System.out.println("Couldn't update -> " + e);
}

Sign up

Use the User.create(String username, String password) method to sign up a new user. If the user name doesn't already exist in the Kinvey backend for your appKey, it will automatically sign in as an active user. If the username does exist, an exception will be thrown.

try{
    User result = mKinveyClient.user().createBlocking(username, password).execute();
} catch (IOException e) {
    System.out.println("Couldn't create -> " + e);
}

Removing the User from the System

You can delete the active user using the User.delete method. This will delete the user entity from the backend.

try{
    mKinveyClient.user().deleteBlocking(true).execute();
} catch (IOException e){
    System.out.println("Couldn't delete -> " + e);
}

You can suspend rather than delete a user by specifying false for the first parameter of the delete method. A suspended user can be reactivated through the Kinvey Console.

try{
    mKinveyClient.user().deleteBlocking(false).execute();
} catch (IOException e){
    System.out.println("Couldn't suspend -> " + e);
}

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

Log in

When a user first installs and runs your app, a login context must be established. This can be accomplished with the User.login method. Normally, once a user logs in, the user context is cached by the client and subequent uses of the app will not require another call to login. However, there are times that you may have to reestablish a login session with the active user.

try{
    User result = mKinveyClient.user().loginBlocking(username, password).execute();
} catch (IOException e) {
    System.out.println("Couldn't login -> " + e);
}

To initiate an implicit login, simply call the loginBlocking method without passing a username or password.

try{
    User result = mKinveyClient.user().loginBlocking().execute();
} catch (IOException e) {
    System.out.println("Couldn't login -> " + e);
}

Log in methods are only needed when a user exists for that app backend but has not been established for that application session. Three common scenarios when this is necessary:

  • when the application launches and a current user is not established in the credential store
  • the user has logged out and the application needs to make more calls to Kinvey

Once the user has been logged in, the library will set it as the active user and cache it.

Log out

mKinveyClient.user().logout().execute() will clear the active user and remove any cached instance of the active user. This method has no effect if there is no active user.

Remember to update if your app is tracking any attributes on the user or you may lose whatever changes were made since the last save.

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 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 User.retrieve method. This method requests an up-to-date copy of all user attributes from the Kinvey server.


try{
    User result = mKinveyClient.user().retrieveBlocking().execute();
} catch (IOException e) {
    System.out.println("Couldn't retrieve -> " + e);
}

Email Confirmation

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 its Settings panel. The following settings are available under Email Verification:

  • Require Email Verification for sign in: 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 this 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 a certain date: this option appears when you enable Require Email Verification for sign in. If enabled, any user 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.
  • Start verification automatically: if this option is enabled, a verification email is automatically sent when a user account is created, or when its email address changes. If this option is not enabled, you will need to manually initiate the email verification process for each user to verify their email address.

  • Customize Kinvey email verification: this section allow you to set up the email and web page templates that are used during the verification process.

To request email verification, use User.sendEmailVerification(). The user must have a valid email set in the email attribute. For example, to send a confirmation email to the active user:

try{
    mKinveyClient.user().sendEmailVerificationBlocking().execute();
} catch (IOException e) {
    System.out.println("Couldn't send email -> " + e);
}

This request starts the email verification process and causes an email to be sent to the user. The email requests that 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 user object field.

Email Verification Request

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

Email Verification Completed

Customization of verification emails

Kinvey provides generic templates for the emails being sent and the web page being shown during the verification. If you want to, you can customize the templates' contents. You can have different text and graphics for each app and even for each app environment.

To customize the templates, take these steps:

  1. Open the Console.
  2. Navigate to Users > Collection Setting > Email Verification.
  3. Find the Customize Kinvey email verification section.
  4. Expand each template to edit it using HTML and Mustache templating.

For the email templates, a plain-text version is generated and sent along if HTML is used in the body.

Email Verification Customization

The From and Reply to fields found on the email templates can be in the form Display Name <account@example.com> or simply account@example.com.

The email is always sent from support@kinvey.com. The From and Reply to fields only set the respective email headers which may cause the message to be flagged by spam filters.

The Subject and Body fields found on the email templates and the Body of the web page support variables. Variables are automatically replaced with appropriate values just before sending each copy of the email or showing each instance of the web page. Mustache templates are used to implement variables, which take the form of tags enclosed in double curly-brackets.

The available variables are predefined and vary by template type. You can't define additional variables.

Verification Email:
  • appname—application's name
  • fname—user's first name, as specified by the first_name field in the user collection
  • username—user's username, as specified by the username field in the user collection
  • url—link that 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—exact date the link will expire
Welcome Email:
  • appname—application's name
  • fname—user's first name, as specified by the first_name field in the user collection.
  • username—user's username, as specified by the username field in the user collection.
  • lastChangedAt—last time the user submitted a new password
Verification successful web page:
  • appname—application's name
  • fname—user's first name, as specified by the first_name field in the user collection
  • username—user's username, as specified by the username field in the user collection
  • lastChangedAt—last time the user submitted a new password

Mustache supports basic flow control through sections. In the following example, the contents of the section starting with {{#fname}} and ending with {{/fname}} will be shown if fname is defined. The second line utilizes an inverse section to show the username in case fname is empty.

{{#fname}}<p>Dear {{fname}},</p>{{/fname}}
{{^fname}}<p>Dear {{username}},</p>{{/fname}}

For advanced usage of sections, see the Mustache documentation.

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.

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.

User Discovery

Often times, apps 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.

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.

It is not possible to fetch all users with an empty query using the 'lookup' method. You should use "query.equalTo" for the query when calling the lookup method. You can lookup users based on the following criteria:

  • username
  • last_name
  • first_name
  • email
  • _socialidentity.facebook.id
UserDiscovery users = mKinveyClient.userDiscovery();
UserLookup criteria = users.userLookup();
criteria.setLastName("dean");
try{
    User[] result = users.lookupBlocking(criteria).execute().
} catch (IOException e) {
    System.out.println("Couldn't lookup -> " + e);
}