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.

Basic User Operations

The User API provides basic CRUD operations that an app can implement for managing users in its backend on Kinvey.

Sign up

Developers that choose to work directly with the User REST API should have POST /user/:appKey/ be the first call to Kinvey for a new application instance (fresh app install). The credentials should then be cached locally and used to authenticate any subsequent requests.

This request must be authenticated using Basic Auth with app credentials. The request body is optional, and may include any fields you might want to capture for the end user.

The sign-up endpoint creates a new user. To obtain a Kinvey auth token that you can use in subsequent authenticated requests, you need to call the login endpoint.

The username is case sensitive. When logging in, the user must use the exact same username case as stored on the backend. You can utilize Business Logic or Flex to implement case-insensitive usernames.

When using custom values for _id, you should avoid values that are exactly 12 or 24 symbols in length. Such values are automatically converted to BSON ObjectID and are not stored as strings in the database, which can interfere with querying and other operations.

To ensure that no items with 12 or 24 symbols long _id are stored in the collection, you can create a pre-save hook that either prevents saving such items, or appends an additional symbol (for example, underscore) to the _id:

if (_id.length === 12 || _id.length === 24) {
  _id += "_";
}

POST /user/:appKey/ HTTP/1.1
Host: baas.kinvey.com
Authorization: [Basic Auth with app credentials]
Content-Type: application/json

[optional body]
HTTP/1.1 201 Created
Location: /user/:appKey/:_id
Content-Type: application/json

{
  "_id": "example-id",
  "username": "example-username",
  "password": "example-password-clear",
  "field1" "additional-field-passed-in",
  "fieldN" "additional-field-passed-in",
  "_kmd": {
    "lmt": "2018-01-04T12:12:44.886Z",
    "ect": "2018-01-04T12:12:44.886Z"
  }
}

If the request does not contain a body, a username and password will be generated by the server and returned in clear text. If a specific username and password pair is needed by an app, they must be passed in fields called username and password respectively. The email address, used for password resets and email verification, must be stored in the email field.

Passwords are stored on the server hashed, using a random salt generated on the server. Subsequent GET requests for the user object do not return the hashed password or the salt.

If a request body is passed, it must be in a json format, and a Content-Type: application/json header must be used.

The returned Location header value can be used later to modify the user object.

The following example request creates a user with a username and password, along with two additional fields named city and interests:

POST /user/:appKey/ HTTP/1.1
Content-Type: application/json
Authorization: [Basic Auth with app credentials]
Content-Type: application/json

{
  "username": "ivan",
  "password": "123456",
  "city": "Boston",
  "interests": "Skiing"
}
HTTP/1.1 201 Created
Location: /user/:appKey/:_id
Content-Type: application/json

{
  "_id": "example-id",
  "username": "ivan",
  "password": "123456",
  "city": "Boston",
  "interests": "Skiing",
  "_kmd": {
    "lmt": "2018-01-04T12:12:44.886Z",
    "ect": "2018-01-04T12:12:44.886Z"
  }
}

Required headers

  • Authorization
  • Content-Type: application/json

Retrieve

A GET to /user/:appKey/:id fetches the user object.

GET /user/:appKey/:id HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]

Authenticate using user credentials. The hashed password and the salt are excluded from the response.

The same robust querying available in the data store is valid for querying users including filtering, grouping and location queries. This querying respects the ACL setup for the collection and the users within.

Required headers

  • Authorization

Update

PUT /user/:appKey/:id HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
Content-Type: application/json

{
  "field1": "new-field",
  "field2": "field-to-be-updated"
}

This request updates the user entity at the location provided and is typically used when the user enters some new piece of information about themselves. Authenticate this request using user credentials.

Note that updating certain properties of a user entity will invalidate any existing user sessions, and generate a new auth token. These properties are: password, email, and _socialIdentity.

Required headers

  • Authorization
  • Content-Type: application/json

Delete

API Version 1

A DELETE request using API Version 1 will purge the user entity from the User collection. Subsequent requests for the same user will return a 404 Not Found error and the deleted user id/name will be available for re-use.

DELETE /user/:appKey/:id HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
X-Kinvey-API-Version: 1
HTTP/1.1 204 No Content

Additionally, with API Version 1 or above, apps have the ability to suspend a user. In API Version 1, this is done by specifying soft=true in the query string. Suspended users can no longer access the app and will receive a 401 error on all requests.

DELETE /user/:appKey/:id?soft=true HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
X-Kinvey-API-Version: 1
HTTP/1.1 204 No Content

User Deletes in API version 1

Suspended users continue to live in the User collection and can be re-enabled using the Master secret by sending a _restore request.

POST /user/:appKey/:id/_restore HTTP/1.1
Host: baas.kinvey.com
Authorization: [master secret]
X-Kinvey-API-Version: 1
HTTP/1.1 204 No Content

API Version 2

Starting with API Version 2, a plain delete that is not accompanied with a query string will automatically default to suspending the user instead of completely removing the entity, as described above.

User Deletes in API version 2

To permanently remove the user, include hard=true in the query string. This will completely remove the user from the User collection, and cannot be undone.

DELETE /user/:appKey/:id?hard=true HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
X-Kinvey-API-Version: 2
HTTP/1.1 204 No Content

Required headers

  • Authorization

Metadata

Every user entity has a _kmd (Kinvey Metadata) JSON object associated with it, which provides meta-information about an entity. The format of this object is:

"_kmd": {
  "lmt": "2013-03-14T15:55:00.329Z",
  "ect": "2013-03-14T15:55:00.329Z"
  "llt": "2013-03-14T15:55:00.329Z"
}

The object exposes the following properties:

  • lmt (last modified time) - holds the time the user entity was last updated on the server.
  • ect (entity creation time) - holds the time the user entity was created on the server. This property will be added to an entity when a user signs up and will remain unchanged for the life of the entity.
  • llt (last login time) - the last login timestamp of a user.

The _kmd object is a system field and cannot be modified by regular users.

However, _kmd.ect and _kmd.lmt can be changed if the request is authenticated using master secret credentials. Be careful if you submit them when updating an entity in this scenario - e.g. the passed values for _kmd.lmt and _kmd.ect will overwrite the autogenerated values of these fields on the server.

_kmd.llt is always autogenerated and cannot be changed even with master secret credentials.

Authentication

User Sessions

User sessions allow you to secure access to the app using authorization tokens that can be controlled on a per session basis. Each session, beginning with a login and ending with a logout, allows you to model well defined periods of user engagement in the app.

To set the user session expiration time on App level (applied to all environments in the app):
Kinvey Console -> App Settings -> Manage App -> User session timeout

To set the user session expiration time on Organization level (applied to all apps in the organization):
Kinvey Console -> Organization settings -> Settings -> User session timeout

App level settings (if set) override Organization level settings.

Generally, a user's session ends when it expires or when logout is called. It is possible, though, to terminate all of the user's sessions at once. Subsequent requests that use any of the destroyed tokens will be rejected.

To invalidate the tokens of a single user:

DELETE /user/:appKey/:userid/tokens HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [user credentials]
HTTP/1.1 204 NoContent
X-Kinvey-Api-Version: 6

To invalidate the tokens of all users:

DELETE /user/:appKey/tokens HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [master credentials]
HTTP/1.1 204 NoContent
X-Kinvey-Api-Version: 6

Login

Login with username and password

An app can use the login method - POST /user/:appKey/login - to log a user in. The method takes a username and password and, when validation is successful, returns the entire user entity.

With API version 1 or higher, the login method will also establish a session and return a Kinvey auth token, in the _kmd.authtoken property, that an app can use in subsequent requests for authentication.

The login request expects the user's credentials in the request body and must be authenticated with the app secret:

POST /user/:appKey/login HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 1
Authorization: [Basic Auth with app credentials]

{
  "username": "ivan",
  "password": "123456"
}
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 1
Content-Type: application/json

{
  "username": "ivan",
  "location": "Cambridge, MA, USA",
  "locale": "en-US",
  "_kmd":
  {
    "lmt":"2012-06-29T13:02:11.864Z",
    "ect":"2012-06-29T13:02:11.864Z",
    "llt":"2012-08-15T13:05:13.681Z",
    "authtoken":"368c9f15-01b4-4a49-9b8d-989f4b2d30ed.Vai/mloxDgUUiSwiRkA9kDvoBu5NvlZaEkGXrREY8G9="
  }
}

The username is case sensitive. When logging in, the user must use the exact same username case as stored on the backend. You can utilize Business Logic or Flex to implement case-insensitive usernames.

Note that updating certain properties of a user entity will invalidate any existing user sessions, and generate a new auth token. These properties are: password, email, and _socialIdentity.

Login with MFA

API version 6 adds support for Multi-factor authentication (MFA). The response body always contains a mfaRequired boolean property that designates whether MFA is required or not. When mfaRequired is false, the user is returned along with an authentication token. When mfaRequired is true, the response body contains an MFA session token, a list of the user's authenticators, and the user's ID.

MFA not required example:

POST /user/:appKey/login HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [Basic Auth with app credentials]

{
  "username": "ivan",
  "password": "123456"
}
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "mfaRequired": false,
  "user": {
     "username": "ivan",
     "location": "Cambridge, MA, USA",
     "locale": "en-US",
     "_kmd":
     {
       "lmt":"2021-06-29T13:02:11.864Z",
       "ect":"2021-06-29T13:02:11.864Z",
       "llt":"2021-08-15T13:05:13.681Z"
     }
  },
  "authToken": "368c9f15-01b4-4a49-9b8d-989f4b2d30ed.Vai/mloxDgUUiSwiRkA9kDvoBu5NvlZaEkGXrREY8G9="
}

MFA required example:

POST /user/:appKey/login HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [Basic Auth with app credentials]

{
  "username": "ivan",
  "password": "123456"
}
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "mfaRequired": true,
  "mfaSessionToken": "368c9f15-01b4-4a49-9b8d-989f4b2d30ed.Vai/mloxDgUUiSwiRkA9kDvoBu5NvlZaEkGXrREY8G9=",
  "authenticators": [{ "id": "e9458ee2-fd72-40b9-8c54-1f12b66c1285", "name": "workPhone", "type": "totp" }],
  "userId": "16b47c09-0150-4546-b9f5-782e04e97b1b"
}

When MFA is required, Kinvey issues an MFA session token (located in mfaSessionToken property). This token is used for authentication (MFA session authentication) to complete the login flow. The user should choose the authenticator that will be used:

POST /user/:appKey/mfa/challenge HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [MFA session authentication]

{
  "authenticatorId": "e9458ee2-fd72-40b9-8c54-1f12b66c1285"
}
HTTP/1.1 204 NoContent
X-Kinvey-Api-Version: 6

The final step is to provide the code generated by the TOTP app:

POST /user/:appKey/mfa/complete HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [MFA session authentication]

{
  "code": "675340",
  "createDeviceToken": true
}
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "mfaRequired": false,
  "user": {
     "username": "ivan",
     "location": "Cambridge, MA, USA",
     "locale": "en-US",
     "_kmd":
     {
       "lmt":"2021-06-29T13:02:11.864Z",
       "ect":"2021-06-29T13:02:11.864Z",
       "llt":"2021-08-15T13:05:13.681Z"
     }
  },
  "authToken": "368c9f15-01b4-4a49-9b8d-989f4b2d30ed.Vai/mloxDgUUiSwiRkA9kDvoBu5NvlZaEkGXrREY8G9=",
  "deviceToken": "hSmYS1x8lve6HGiKdfp7McvRFBsEm3vCh7fdOzqf0.BxEpj/j1a4GtycNJbY8G/lOj/gYJlRJMOemyeNgvWao="
}

Apart from the code, you can also specify whether a device token should be created or not: createDeviceToken: true. If the user trusts the device, creating a device token and providing it the next time user tries to log in, could spare them the second-factor login. The device token is specified as deviceToken in the /login request.

Login with recovery code

When MFA is enabled, an alternative to logging in with an authentication code is logging in with a recovery code. You can use it when the user has lost access to their device or has some other issue preventing them from providing an authentication code.

POST /user/:appKey/login HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [Basic Auth with app credentials]

{
  "username": "ivan",
  "password": "123456",
  "recoveryCode": "31fc-8178-80b1"
}
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "mfaRequired": false,
  "user": {
     "username": "ivan",
     "location": "Cambridge, MA, USA",
     "locale": "en-US",
     "_kmd":
     {
       "lmt":"2021-06-29T13:02:11.864Z",
       "ect":"2021-06-29T13:02:11.864Z",
       "llt":"2021-08-15T13:05:13.681Z"
     }
  },
  "authToken": "368c9f15-01b4-4a49-9b8d-989f4b2d30ed.Vai/mloxDgUUiSwiRkA9kDvoBu5NvlZaEkGXrREY8G9="
}

Required headers

  • Authorization
  • Content-Type: application/json

An app can retrieve information on the logged in user by using GET /user/:appKey/_me. The request must be authenticated using either Basic Auth or Session Auth. This method will return the entire user entity for the authenticated user.

GET /user/:appKey/_me HTTP/1.1
Authorization: [user credentials]
HTTP/1.1 200 OK
Content-Type: application/json

{
  "username": "ivan",
  "location": "Cambridge, MA, USA",
  "locale": "en-US",
  "_kmd":
  {
    "lmt":"2012-06-29T13:02:11.864Z"
    "ect":"2012-06-29T13:02:11.864Z",
    "llt":"2012-08-15T13:05:13.681Z"
    "authtoken":"368c9f15-01b4-4a49-9b8d-989f4b2d30ed.Vai/mloxDgUUiSwiRkA9kDvoBu5NvlZaEkGXrREY8G9="
  }
}

Note that version 6 of the API no longer generates and returns an authtoken.

Required headers

  • Authorization

Last Login Time of a user

Every time a user logs on, the logon time is stamped into the _kmd.llt attribute of the user. This can help to find and disable inactive accounts

Login hooks

Login hooks allow you to add server-side logic right before or right after a user logs in.

Login hooks can be used for various tasks. For example:

  • Restrict login for specific users - in onPreLogin, you can return an error instead of continuing with the login process.
  • Implement failed login count - in onLoginFailure, you may store a failed login count for the user in a separate collection or the user object itself.
  • Notify on failed login - send an email or push notification to a device.
  • Notify on successful login - send an email or push notification to a device.
  • Implement a case-insensitive mechanism for username on login in one place, on the server - in onPrelogin hook, convert the username to lower case.
  • Create a login log - in onLoginFialure and onLoginSuccess add an item to a “loginLog” collection.

More details on using login hooks can be found here.

Logout

When using Session Auth, the app can logout and terminate a user session by sending a POST request to /user/:appKey/_logout.

When authenticated with a valid Kinvey auth token, the logout request will destroy the token and return a HTTP 204 response. Any subsequent requests that use the same auth token will be rejected with the HTTP 401 Unauthorized response.

This method is only available when using API version 1 or higher.

POST /user/:appKey/_logout HTTP/1.1
X-Kinvey-Api-Version: 1
Authorization: Kinvey [auth token]
HTTP/1.1 204 OK
X-Kinvey-Api-Version: 1

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

User management features provide fully automated workflows that can be used to easily manage and secure user account information.

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 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.

Workflow

The email verification process may be started either automatically as described in Configuration or manually. To manually initiate the email verification process for a user, send a POST request with an empty body to Kinvey, as follows:

POST /rpc/:appKey/:username/user-email-verification-initiate HTTP/1.1
Host: baas.kinvey.com
Authorization: [Basic Auth with app credentials]
HTTP/1.1 204 No Content

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

If the user started the verification process, the current verification status will be available in the _kmd.emailVerification property of the user entity.

{
   "_id":"507242b8a8fd60a5120020b4"
   "username":"2f127d3e-94ad-44fa-8cbe-48fde6ca12bb",
   "email":"johndoe@kinvey.com",
   "_kmd":
   {
      "lmt":"2012-10-08T03:04:24.034Z",
      "ect":"2012-10-08T03:04:24.034Z",
      "emailVerification":
      {
        "status":"confirmed",
        "lastStateChangeAt":"2012-10-10T19:56:03.282Z",
        "lastConfirmedAt":"2012-10-10T19:56:03.282Z",
        "emailAddress":"johndoe@kinvey.com"
      }
   },
   "_acl":
   {
     "creator":"507242b8a8fd60a5120020b4"
   }
}

The verification workflow exposes the following states in the status property:

  • 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 in the lastStateChangeAt property.

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

Note that the email address currently being verified is recorded in the emailAddress property of the _kmd.emailVerification object. Should the user change their email address (by changing the email property of their entity in the Users collection) while a verification is in progress, Kinvey will terminate the verification process for the previous email address, and start from the beginning with the new email address when a new initiate request is received.

The emailVerification object also tracks the last time the email address was confirmed in the lastConfirmedAt property. This is helpful if an app chooses to implement features to ensure ongoing validity of the email address on record.

Required headers

  • Authorization

Customization of verification templates

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

Kinvey allows you to build a password reset feature in your app, through which your users can establish new passwords when needed.

To request a password reset, send a POST request with an empty body to /rpc/:appKey/:username/user-password-reset-initiate:

POST /rpc/:appKey/:username/user-password-reset-initiate HTTP/1.1
Host: baas.kinvey.com
Authorization: [Basic Auth with app credentials]
HTTP/1.1 204 No Content

Note that it is also possible to initiate the password reset process using a user's email address instead of username. To do so, replace the username in the request above with the user's email, as follows:

POST /rpc/:appKey/:email/user-password-reset-initiate HTTP/1.1
Host: baas.kinvey.com
Authorization: [Basic Auth with app credentials]
HTTP/1.1 204 No Content

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

The current reset status for a user is available in the _kmd.passwordReset property of the user entity.

{
   "_id":"507242b8a8fd60a5120020b4"
   "username":"2f127d3e-94ad-44fa-8cbe-48fde6ca12bb",
   "email":"johndoe@kinvey.com",
   "_kmd":
   {
      "lmt":"2012-10-08T03:04:24.034Z",
      "ect":"2012-10-08T03:04:24.034Z",
      "llt":"2012-10-08T03:04:24.034Z",
      "passwordReset":
      {
        "status":"InProgress",
        "lastStateChangeAt":"2012-10-10T19:56:03.282Z"
      }
   },
   "_acl":
   {
     "creator":"507242b8a8fd60a5120020b4"
   }
}

A status value of InProgress implies that a password reset email was sent at the time recorded in the lastStateChangeAt property. Once the user completes a reset, the status value changes to an empty string and the lastStateChangeAt property reflects the time the password reset was completed.

Required headers

  • Authorization

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.

Multi-factor authentication

You can use Multi-factor authentication (MFA) to provide a more secure login in your app. The feature is available as of version 6 of the Kinvey API.

Kinvey supports time-based one-time password (TOTP) as a form of MFA. Each user can have one or more Kinvey authenticators - sources of second-factor authentication. This provides you with the opportunity to allow the users of your app to set up multiple devices. MFA is considered enabled for a certain user if they have at least one Kinvey authenticator. If you don't wish to support multiple authenticators, you can restrict the users in your app to having just one.

Setup

Authenticator setup is a two-step process. First, Kinvey creates the authenticator and generates a secret, and then it verifies it. An authenticator app of choice uses the secret to generate a new authentication code after a certain amount of time (generally, 30 seconds). This code, along with username and password, is used to log in the user. It is also used to complete the Kinvey authenticator setup.

When MFA is enabled (i.e. the first Kinvey authenticator is created), recovery codes are generated and returned from the Kinvey API. It is wise to encourage the user to save them now, although they can be retrieved later as well.

The recovery codes can be used as a backup login method when the user has lost access to their device.

Create Kinvey authenticator:

POST /user/:appKey/:userid/authenticators HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [user credentials]

{
  "type": "totp",
  "name": "workPhone"
}
HTTP/1.1 201 Created
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "type": "totp",
  "name": "workPhone",
  "config": {
    "secret": "GIKGIZT3KECAIN2V",
    "otpAuthUrl": "otpauth://totp/Kinvey:71699502-0f3b-4a25-b7c7-ba0b82be07db?secret=GIKGIZT3KECAIN2V&period=30&digits=6&algorithm=SHA1&issuer=Kinvey"
  },
  "id": "ff42a2d7-b5e4-4d9b-b5a3-56102bb1c31b"
}

Verify Kinvey authenticator:

POST /user/:appKey/:userid/authenticators/:authenticatorId/verify HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [user credentials]

{
  "code": "740245"
}
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "recoveryCodes": [
    "31fc-8178-80b1",
    "55ee-1e5f-fcab",
    "e1a2-c2ce-58be",
    "f959-3bbe-e8b7",
    "2f92-0cef-69ea",
    "ae3a-049f-37ff",
    "5616-fc07-2f95",
    "6336-29ad-0816",
    "b5b4-44e8-b883",
    "5a10-271f-cf9b"
  ]
}

Please, note that the response body contains recovery codes only when the user sets up MFA for the first time.

Settings

You can adjust specific MFA settings for your app in the Kinvey Console. Navigate to User settings to:

  • Require two-factor authentication - when enabled, users will be required to set up two-factor authentication before they can log in. Users who do not have the MFA set up, will have the chance to do it on the next login attempt.

  • Enable device tokens - after successful two-factor authentication, users will be issued a device token that allows them to bypass two-factor authentication for a certain period.

  • Device token expiration - set the expiration period of the device token in days.

Console MFA settings

Management

You can provide your app users with the ability to manage their MFA setup - to add new authenticators, remove existing or disable MFA altogether.

To check if the user has enabled MFA, you can list their authenticators:

GET /user/:appKey/:userid/authenticators HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [user credentials]
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

[
  {
    "type": "totp",
    "name": "workPhone",
    "id": "ff42a2d7-b5e4-4d9b-b5a3-56102bb1c31b"
  }
]

To remove an existing authenticator:

DELETE /user/:appKey/:userid/authenticators/:authenticatorId HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [user credentials]
HTTP/1.1 204 No Content
X-Kinvey-Api-Version: 6

Removing the last authenticator disables MFA and deletes the recovery codes. New recovery codes will be generated if MFA setup is done again (a Kinvey authenticator is created and verified).

Recovery codes are returned when user setups MFA but they can also be fetched any time:

GET /user/:appKey/:userid/recovery-codes HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [user credentials]
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "recoveryCodes": [
    "31fc-8178-80b1",
    "55ee-1e5f-fcab",
    "e1a2-c2ce-58be",
    "f959-3bbe-e8b7",
    "2f92-0cef-69ea",
    "ae3a-049f-37ff",
    "5616-fc07-2f95",
    "6336-29ad-0816",
    "b5b4-44e8-b883",
    "5a10-271f-cf9b"
  ]
}

If you wish to regenerate them:

POST /user/:appKey/:userid/recovery-codes HTTP/1.1
Content-Type: application/json
X-Kinvey-Api-Version: 6
Authorization: [user credentials]
HTTP/1.1 200 OK
X-Kinvey-Api-Version: 6
Content-Type: application/json

{
  "recoveryCodes": [
    "289d-e532-ea1d",
    "f130-2114-0c46",
    "74de-5c91-958e",
    "37a8-a2d8-cd25",
    "ff38-d760-2171",
    "19dd-91fd-694e",
    "7f6a-0019-0671",
    "dbde-f5ba-5ab9",
    "04ff-b0c8-6aeb",
    "3021-7492-9e32"
  ]
}

For information on how to login with MFA, please go to login.

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, Google+, or LinkedIn accounts, you eliminate a source of friction by not requiring that users create usernames and passwords just for your app.

Kinvey uses its Mobile Identity Connect (MIC) framework to connect to social identity providers (IdPs). This way, you have the benefit of using unified methods for connecting to all your IdPs—social, enterprise, and so on.

Service Settings

Before you can use MIC, you need to set up a RapidAuth service in the Kinvey Console for each IdP you want to connect to.

Facebook uses the Facebook Auth connector while Google and LinkedIn use the OAuth2 connector. Consult the following tables to learn how to quickly set up these RapidAuth connectors.

Facebook

The Facebook Auth connector has the benefit of having all invariable connection and other settings set for you. For the rest of the settings, see Facebook Auth in the MIC guide.

SettingValue
Client IDFacebook-provided ID
Client SecretFacebook-provided secret
User ID Attributeid
Redirect URI'sIn case you are using a custom redirect URL (i.e., you are not using a Kinvey client SDK), whitelist it here
ScopeSpecify the user attributes to request from the IdP

Google

Start an OAuth2 RadpidAuth connector and set it up as shown below. Note that depending on your use case, you may want to configure additional settings.

SettingValue
Provider URIhttps://www.googleapis.com/oauth2/v4/token
Grant TypeAuthorization Code
Grant Endpointhttps://accounts.google.com/o/oauth2/v2/auth
Client IDGoogle-provided ID
Client SecretGoogle-provided secret
User ID Attributeid
User ID Endpointhttps://www.googleapis.com/oauth2/v1/userinfo
Redirect URI'sIn case you are using a custom redirect URL (i.e., you are not using a Kinvey client SDK), whitelist it here
ScopeSpecify the user attributes to request from the IdP

LinkedIn

Start an OAuth2 RadpidAuth connector and set it up as shown below. Note that depending on your use case, you may want to configure additional settings.

SettingValue
Provider URIhttps://www.linkedin.com/uas/oauth2/accessToken
Grant TypeAuthorization Code
Grant Endpointhttps://www.linkedin.com/uas/oauth2/authorization
Client IDLinkedIn-provided ID
Client SecretLinkedIn-provided secret
User ID Attributeid
User ID Endpointhttps://api.linkedin.com/v1/people/~?format=json
Redirect URI'sIn case you are using a custom redirect URL (i.e., you are not using a Kinvey client SDK), whitelist it here
ScopeSpecify the user attributes to request from the IdP
Include client id in token request?Yes
Include client secret in token request?Yes

IdP Settings

After setting up a service using the Kinvey Console, you need to set the IdP to work with Kinvey.

Facebook

Set your Facebook app to allow a redirect URI used internally by Kinvey. Log in to your Facebook developer account, open the app, go to Facebook Login > Settings> Valid OAuth Redirect URIs, and enter the following URI:

https://auth.kinvey.com/facebook/redirect

Customers with dedicated Kinvey instances and Progress Health Cloud customers need to prepend their Instance ID to the MIC base URL as follows:

https://<instance>-auth.kinvey.com

You can find your Instance ID on the dashboard of the Kinvey Console, next to your App Key and App Secret.

LinkedIn

Set your LinkedIn app to allow a redirect URI used internally by Kinvey. Log in to your LinkedIn developer account, open the app, find the OAuth 2.0 section and ensure that the Authorized Redirect URLs contains the following URL:

https://auth.kinvey.com/oauth2/redirect

Customers with dedicated Kinvey instances and Progress Health Cloud customers need to prepend their Instance ID to the MIC base URL as follows:

https://<instance>-auth.kinvey.com

You can find your Instance ID on the dashboard of the Kinvey Console, next to your App Key and App Secret.

Google

Set your Google app to allow a redirect URI used internally by Kinvey. Log in to Google API Console and then:

  1. Open the Credentials page.
  2. Click Create credentials > OAuth client ID.
  3. For Application type, select Web application.
  4. In the Authorized redirect URIs text box that appears, enter the following URL:
https://auth.kinvey.com/oauth2/redirect

Customers with dedicated Kinvey instances and Progress Health Cloud customers need to prepend their Instance ID to the MIC base URL as follows:

https://<instance>-auth.kinvey.com

You can find your Instance ID on the dashboard of the Kinvey Console, next to your App Key and App Secret.

Logging In

Social login relies on MIC. If an existing Kinvey user is logged in to the app, MIC updates the user account with the passed social identity information. If not, it looks for an existing Kinvey user that shares the same OAuth access token and logs them in. Finally, if such a user does not exist, MIC creates a new user account and associates the social identity with it.

Go to the Mobile Identity Connect guide to learn how to log in with MIC.

User Discovery

The full range of access control mechanisms is available for users. For example: an app may choose to mark the User collection Private, which will prevent one user from accessing another user's data. However, keeping user data hidden prevents app users from discovering other users, thus reducing the social value of the app. The _lookup method allows an app to respect user privacy but enable user discovery at the same time.

The lookup method provides a very limited way to query and retrieve some basic attributes on other users.

POST /user/:appKey/_lookup HTTP/1.1
Content-Type: application/json
Authorization: [user credentials]

{
  "username": "tom"
  "last_name": "Newman"
}
HTTP/1.1 200 OK
Content-Type: application/json

{
  "_id": "58295028829"
  "username": "tom",
  "first_name": "Thomas"
  "last_name": "Newman"
  "email": "thomas.newman@emailprovider.com"
}

This method allows users to do exact queries for other users restricted to the following attributes:

  • _id
  • username
  • first_name
  • last_name
  • email
  • _socialIdentity.facebook.id
  • _socialIdentity.facebook.name
  • _socialIdentity.twitter.id
  • _socialIdentity.twitter.name
  • _socialIdentity.google.id
  • _socialIdentity.google.given_name
  • _socialIdentity.google.family_name
  • _socialIdentity.linkedIn.id
  • _socialIdentity.linkedIn.firstName
  • _socialIdentity.linkedIn.lastName

The method accepts attributes in the request body and presence of more than one attribute is treated as a logical conjunction of all attributes. Any other attributes in the User collection are hidden in the lookup method. A future release will allow the ability to configure this list through the Kinvey Console.

Note an app can always use fine grained permissions for allowing one user to grant access to another user when the collection is marked Private. When enabled, fine grained permissions open up access to the entire user object through other API methods.

Required headers

  • Authorization
  • Content-Type: application/json

User Groups

User groups allow an app to aggregate application users into groups and setup access control based on group membership. Access control automatically adjusts when a user joins or leaves a group.

Create

POST /group/:appKey/ HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
Content-Type: application/json

{
  "_id": "G",
  "users": {
    "all": false,
    "list": [
       { "_type": "KinveyRef", "_collection": "user", "_id": "1" },
       { "_type": "KinveyRef", "_collection": "user", "_id": "3" },
       { "_type": "KinveyRef", "_collection": "user", "_id": "4" }
    ]
  },
  "groups": [
    { "_type": "KinveyRef", "_collection": "group", "_id": "G1" },
    { "_type": "KinveyRef", "_collection": "group", "_id": "G5" }
  ]
}
HTTP/1.1 201 Created
Location: /group/:appKey/:_id
Content-Type: application/json

{
  "_id": "G",
  "users": {
    "all": false,
    "list": [
       { _type: "KinveyRef", _collection: "user", _id: "1" },
       { _type: "KinveyRef", _collection: "user", _id: "3" },
       { _type: "KinveyRef", _collection: "user", _id: "4" }
    ]
  },
  "groups": [
    { _type: "KinveyRef", _collection: "group", _id: "G1" },
    { _type: "KinveyRef", _collection: "group", _id: "G5" }
  ],
  "_acl": {
    "creator": "5058c666474f050906000001"
  },
  "_kmd": {
    "lmt": "2012-10-20T22:01:25.159Z",
    "ect": "2012-10-20T22:01:25.159Z",
    "llt": "2012-10-20T22:01:25.159Z"
  }
}

Individual users can be included in a group by adding Kinvey references to the list array under the users property. Each reference links to a user within the app by specifying that user's _id. When an entity grants access to a group, every user listed in that group's users.list array is granted the same access.

If the all property of a group is set to true, all users of the app will be part of the group.

A group can also contain one or more nested groups. Every group listed in the groups array gets access to all entities that grant access to the containing group. Much like the users.list array mentioned above, the groups array contains Kinvey references, each referring to a specific group by that group's _id.

An app can use this functionality to model nested access via groups. For example: an app may grant access to company policy documents to the group "employees". The "employees" group contains the groups "managers" and "directors", since all managers and all directors are also employees of the company. By granting 'read' access to the group "employees", an app automatically grants read access to the groups "managers" and "directors".

Groups can be nested up to three levels deep. Please contact Kinvey support to discuss deeper nesting.

Authentication and authorization for group creation follows regular access control.

Required headers

  • Authorization
  • Content-Type: application/json

List

A GET to /group/:appKey will return all group objects.

GET /group/:appKey HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
HTTP/1.1 200 OK
Location: /group/:appKey
Content-Type: application/json

[{
  "_id": "A",
  "users": {
    "all": false,
    "list": [
       { _type: "KinveyRef", _collection: "user", _id: "1" }
    ]
  },
  "_acl": {
    "creator": "5058c666474f050906000001"
  },
  "_kmd": {
    "lmt": "2012-10-20T22:01:25.159Z",
    "ect": "2012-10-20T22:01:25.159Z",
    "llt": "2012-10-20T22:01:25.159Z",
  }
}, {
  "_id": "B",
  "users": {
    "all": true
  },
  "_acl": {
    "creator": "5058c666474f050906000001"
  },
  "_kmd": {
    "lmt": "2012-11-20T22:01:25.159Z",
    "ect": "2012-11-20T22:01:25.159Z",
    "llt": "2012-11-20T22:01:25.159Z"
  }
}]

Authenticate using user context or master secret. Authorization for reads follows regular access control.

Required headers

  • Authorization

Retrieve

A GET to /group/:appKey/:id fetches the group object.

GET /group/:appKey/:id HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]

Authenticate using user context or master secret. Authorization for reads follows regular access control.

Required headers

  • Authorization

Update

PUT /group/:appKey/:id HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
Content-Type: application/json

<JSON-Document-representing-UserGroup>

Use an Update request to change members of the group and/or change the groups contained in the group. Authentication and authorization for updates follows regular access control.

Required headers

  • Authorization
  • Content-Type: application/json

Delete

A group can be removed by issuing a delete request.

It's important that the app admin clean ACL metadata in the backend before deleting a group in order to prevent a reincarnation of the same group from getting access based on old metadata.

DELETE /group/:appKey/:id HTTP/1.1
Host: baas.kinvey.com
Authorization: [user credentials]
HTTP/1.1 204 No Content

Authentication and authorization for deletes follows regular access control.

Required headers

  • Authorization

Username Existence Check

In order to quickly check whether a specific username already exists within your app, you can use the check-username-exists RPC endpoint. To do so, POST a request to /rpc/:appKey/check-username-exists using your app credentials. The body of the request should contain a JSON object having a username field, which contains the username which you would like to check.

POST /rpc/:appKey/check-username-exists HTTP/1.1
Host: baas.kinvey.com
Authorization: [Basic Auth with app credentials]
Content-Type: application/json

{
  "username": "the-username-to-check"
}

Kinvey will respond with a JSON object having a usernameExists field, which is set to true if the username exists within your app, or false if the username does not yet exist.

HTTP/1.1 200 OK
Content-Type: application/json

{
  "usernameExists": "false"
}

Required headers

  • Authorization
  • Content-Type: application/json

Locked-down Users

The app administrator has the ability to lock-down a user. When a user is in locked-down state, any requests that are authenticated with this user's credentials or that attempt to log-in the user will fail. Additionally, all auth tokens for the user will be destroyed. Since this is an administrative operation, only the master secret can be used to lock-down a user (or unlock that user if already locked-down). In order to lock a user down, use the lockdown-user RPC endpoint as follows:

POST /rpc/:appKey/lockdown-user HTTP/1.1
Host: baas.kinvey.com
Authorization: [Basic Auth with master credentials]
Content-Type: application/json

{
  "userId": "the-id-of-the-user-to-lock-down",
  "setLockdownStateTo": true/false
}

If the request was successful, Kinvey will respond with a JSON object containing the current status of the lock-down flag, and a status code of 200.

HTTP/1.1 200 OK
Content-Type: application/json

{
  currentLockdownStatus: true/false
}

Authorization

Controlling user access to your app's resources is achieved through collection- and entity-level permissions, which rely on roles. To learn more about setting permissions, head to the Security guide. Role management is described in Roles.