Simple Authentication

Overview

The central object in the Realm Object Server is the Realm User (SyncUser). The Realm User identifies the application end user, and is used with the server's access control functionality to securely control what data is synchronized.

Realm Platform provides a built-in authentication provider which supports Username/Password and Anonymous login for development and proof of concept usage. This allows client applications to register multiple unique user IDs before focusing development on interoperability with a sophisticated authentication protocol. There are some production scenarios where unauthenticated realm access is practical -- an e-commerce site granting access to a catalog -- but it is not generally advised.

Username/Password Authentication

Realm does not recommend using these authentication methods in a production environment. Instead we recommend using our JWT Authentication Provider

Client Authentication

In order to negotiate username/password authentication, there must be a valid username/password pair defined in the server, and the client needs to know three things: the authentication type, where to send the authentication request, and the valid username/password to send. Login Users shows code examples of configured login requests. The sub-sections below break the login request down to its component parts.

Login Users

Swift
Objective-C
Java
Javascript
.Net
Swift
let auth_url = URL(string: "https://myinstance.cloud.realm.io")!
let creds = SyncCredentials.usernamePassword(username: "username", password: "password", register: false)
SyncUser.logIn(with: creds, server: auth_url, onCompletion: { [weak self](user, err) in
if let _ = user {
// User is logged in
} else if let error = err {
fatalError(error.localizedDescription)
}
} register:NO];
Objective-C
NSURL *authURL = [NSURL URLWithString:@"https://myinstance.cloud.realm.io"]
RLMSyncCredentials *usernameCredentials = [RLMSyncCredentials credentialsWithUsername:@"username" password:@"password" register:NO];
[RLMSyncUser logInWithCredentials:creds authServerURL:authUrl onCompletion:^(RLMSyncUser *syncUser, NSError *error) {
// ...
});
}];
Java
String authURL = "https://myinstance.cloud.realm.io";
SyncCredentials credentials = SyncCredentials.usernamePassword(username, password, false);
SyncUser.logInAsync(credentials, authurl, new SyncUser.Callback<SyncUser>() {
@Override
public void onSuccess(SyncUser user) {
// User is logged
}
@Override
public void onError(ObjectServerError error) {
// Handle error
}
});
Javascript
const authUrl = 'https://myinstance.cloud.realm.io';
let creds = Realm.Sync.Credentials.usernamePassword('username', 'password', true) // createUser = true
Realm.Sync.User.login(authUrl, creds).then(user => {
// user is logged in
// do stuff ...
}).catch(error => {
// an auth error has occurred
});
.Net
var authUrl = new Uri("https://myinstance.cloud.realm.io");
var credentials = Credentials.UsernamePassword(username, password, createUser: false);
var user = await User.LoginAsync(credentials, authUrl);

Server URL

To authenticate, you must supply a server URL. This is the base URL for your server, such as https://myinstance.cloud.realm.io or http://127.0.0.1:9080.

Note the authentication URL uses the http/https URL prefix scheme, as user authentication is handled via standard HTTP. Do not confuse the authentication URL structure with the Realm sync URL realm/realms scheme.

Swift
Objective-C
Java
Javascript
.Net
Swift

The authentication server URL is simply a URL representing the location of the Realm Object Server.

let authURL = URL(string: "https://myinstance.cloud.realm.io")!
Objective-C

The authentication server URL is simply a NSURL representing the location of the Realm Object Server.

NSURL *authURL = [NSURL URLWithString:@"https://myinstance.cloud.realm.io"];
Java

The authentication server URL is simply a URL representing the location of the Realm Object Server.

String authURL = "https://myinstance.cloud.realm.io"
Javascript

The authentication server URL is simply a URL representing the location of the Realm Object Server.

const authURL = 'https://myinstance.cloud.realm.io';
.Net

The authentication server URL is simply a URL representing the location of the Realm Object Server.

var authURL = new Uri("https://myinstance.cloud.realm.io");

Credentials

Swift
Objective-C
Java
Javascript
.NET
Swift
let usernameCredentials = SyncCredentials.usernamePassword(username: "username", password: "password", register: true)

Note that the factory method takes a register boolean argument that indicates whether a new user should be registered or an existing user should be logged in. An error will be thrown if your application tries to register a new user with the username of an existing user, or tries to log in a user that does not exist.

Objective-C
RLMSyncCredentials *usernameCredentials = [RLMSyncCredentials credentialsWithUsername:@"username"
password:@"password"
register:NO];

Note that the factory method takes a register boolean argument that indicates whether a new user should be registered or an existing user should be logged in. An error will be thrown if your application tries to register a new user with the username of an existing user, or tries to log in a user that does not exist.

Java
String username = "jane"
String password = "doe"
boolean createUser = true;
SyncCredentials credentials = SyncCredentials.usernamePassword(username, password, createUser);

Note that the factory method takes a createUser boolean argument that indicates whether a new user should be registered and created or an existing user should be logged in. An error will be thrown if your application tries to register a new user with the username of an existing user, or tries to log in a user that does not exist.

Javascript
let creds = Realm.Sync.Credentials.usernamePassword('username', 'password', true) // createUser = true

The createUser boolean determines if the user should be created. If true is provided and the user exists, or false is provided and the user doesn't exist, an error will be thrown. If not specified, if the user doesn't exist, they will be created, otherwise, they'll be logged in if the password matches

.NET
var credentials = Credentials.UsernamePassword(username, password, createUser: true);

The third parameter of UsernamePassword() is the createUser flag which should only be true the first time, as it indicates that the user should be created. Once the user is created, the parameter must be set to false.

Users will not be created--or an error indicating that those credentials exist--until those credentials are passed into a login function.

Change Password

To update the password on the on a realm account you may choose to use the SyncUser to directly change the password or initiate a password reset process that uses a token sent via email.

Directly Changing the Password

Swift
Objective-C
Java
Javascript
.Net
Swift

Change Current User's Password

Users who authenticate using the built-in Realm Object Server username/password credential type may change their own passwords by calling the SyncUser.changePassword(_:, completion:) API.

This API makes an asynchronous call to the server. The completion block will be called once a response is received, and will be passed in an error if the operation failed, or nil if the operation succeeded.

let newPassword = "swordfish"
user.changePassword(newPassword) { (error) in
if let error = error {
// Something went wrong
}
// Otherwise, the password was successfully changed.
}

Change Another User's Password

Administrators may change the password of any user by calling the SyncUser.changePassword(_:, forUserID:, completion:) API. Pass in the user identity of the user whose password should be changed.

let newPassword = "swordfish"
adminUser.changePassword(newPassword, forUserID: "12345...") { (error) in
if let error = error {
// Something went wrong
}
// Otherwise, the password was successfully changed.
}
Objective-C

Change Current User's Password

Users who authenticate using the built-in Realm Object Server username/password credential type may change their own passwords by calling the -[RLMSyncUser changePassword:completion:] API.

This API makes an asynchronous call to the server. The completion block will be called once a response is received, and will be passed in an error if the operation failed, or nil if the operation succeeded.

NSString *newPassword = @"swordfish";
[user changePassword:newPassword
completion:^(NSError *error) {
if (error) {
// Something went wrong
}
// Otherwise, the password was successfully changed.
}];

Change Another User's Password

Administrators may change the password of any user by calling the -[RLMSyncUser changePassword:forUserID:completion:] API. Pass in the user identity of the user whose password should be changed.

NSString *newPassword = @"swordfish";
[adminUser changePassword:newPassword
forUserId:@"12345..."
completion:^(NSError *error) {
if (error) {
// Something went wrong
}
// Otherwise, the password was successfully changed.
}];
Java

Change Current User's Password

Users who authenticate using the built-in Realm Object Server username/password credential type may change their own passwords by calling the either the SyncUser.changePassword() or SyncUser.changePasswordAsync()API.

This API makes a call to the server. Once the method returns, the user will have updated their password. If any error happens, either an exception is thrown or it is delivered in the callback.

SyncUser user = SyncUser.currentUser();
// Change password on a background thread
try {
user.changePassword("new-password);
// Password was successfully changed
} catch (ObjectServerError error) {
// Something went wrong
}
// Change password from the UI thread
user.changePasswordAsync("new-password", new SyncUser.Callback<SyncUser>() {
@Override
public void onSuccess(SyncUser user) {
// Password for 'user' was succesfully changed.
}
@Override
public void onError(ObjectServerError error) {
// Something went wrong
}
});
Javascript

Javascript requires the use of the password reset process which is detailed below

.Net

To change a user’s password, you can use User.ChangePasswordAsync:

var currentUser = User.Current;
await currentUser.ChangePasswordAsync("new-secure-password");
// The user's password has been changed, they'll no longer be able to use their old password.

Admin users may change other users’ passwords (e.g. as part of a server-side app that automates password retrieval) by passing in a user’s Id:

var adminUser = await User.LoginAsync(...);
await adminUser.ChangePasswordAsync("some-user-id", "new-secure-password");
// The password of the user with Id some-user-id has been changed to new-secure-password.

Request Password Reset

Users who authenticate using the built-in Realm Object Server username/password credential type may initiate a password reset if they used a valid email as their username, this is done in two steps:

  1. Request a password reset:

Swift
Objective-C
Java
Javascript
.NET
Swift
let serverURL = URL(string: "https://foo.us1.realm.cloud.io")
let email = "user@email.com"
SyncUser.requestPasswordReset(forAuthServer: serverURL, userEmail: email) { error in
if error {
// something went wrong
}
}
Objective-C
NSURL *serverURL = [NSURL URLWithString:@"https://foo.us1.realm.cloud.io"];
NSString *email = @"user@email.com";
[RLMSyncUser requestPasswordResetForAuthServer:serverURL userEmail:email completion:^(NSError *error) {
if (error) {
// Something went wrong
}
}];
Java
SyncUser.requestPasswordResetAsync("user@email.com", "https://foo.us1.realm.cloud.io", new SyncUser.Callback<Void>() {
@Override
public void onSuccess(Void result) {
}
@Override
public void onError(ObjectServerError error) {
}
});
Javascript
Realm.Sync.User.requestPasswordReset('https://foo.us1.realm.cloud.io', 'user@email.com').then(() => {
// query sent successfully.
}).catch((error) => {
// an error has occurred
});
.NET
var serverUri = new Uri("https://foo.us1.realm.cloud.io");
await User.RequestPasswordResetAsync(serverUri, "user@email.com");
  1. Complete the password reset using the token sent by email, this can be completed by clicking on the link inside the email or via the API if we manage to extract the token from the email (using deep linking for instance):

Swift
Objective-C
Java
Javascript
.NET
Swift
let serverURL = URL(string: "https://foo.us1.realm.cloud.io")
let token = "resetToken"
let newPassword = "newPassword"
SyncUser.completePasswordReset(forAuthServer: serverURL, token: token, password: newPassword) { error in
if error {
// something went wrong
}
}
Objective-C
NSURL *serverURL = [NSURL URLWithString:@"https://foo.us1.realm.cloud.io"];
NSString *token = @"reset_token";
NSString *newPassword = @"newPassword";
[RLMSyncUser completePasswordResetForAuthServer:serverURL token:token password:newPassword completion:^(NSError *error) {
if (error) {
// Something went wrong
}
}];
Java
SyncUser.completePasswordResetAsync("reset_token", "newPassword", "https://foo.us1.realm.cloud.io", new SyncUser.Callback<Void>() {
@Override
public void onSuccess(Void result) {
}
@Override
public void onError(ObjectServerError error) {
}
});
Javascript
Realm.Sync.User.completePasswordReset('https://foo.us1.realm.cloud.io', 'reset_token', 'new_password').then(() => {
// query sent successfully.
}).catch((error) => {
// an error has occurred
});
.NET
var serverUri = new Uri("https://foo.us1.realm.cloud.io");
await User.CompletePasswordResetAsync(serverUri, "reset_token", "newPassword");

Working with Email Addresses

Your Realm Cloud instance is, by default, configured to accept username/password authentication. If you want, you can jump straight to the Client Configuration below. This section will walk you through setting up email confirmation.

Cloud
Self-Hosted
Cloud

Realm Cloud is configured to send emails in order to allow users to complete a password reset or email confirmation flow. This is enabled by default, however, if you want to override this configuration (example for strong branding) you can specify a custom SMTP and email sender.

  • Navigate to your instance settings

  • Select the Username / Password provider, then check "send emails" to activate the option.

To send confirmation emails from a different server, uncheck "Use the email configuration provided by Realm Cloud," and fill in the "SMTP Connection String" and "Send emails from field."

If a Realm user's username is a valid email address, there is additional functionality that can be used:

Setting up Email Confirmation

After registering a new user, we can perform email confirmation if the username is a valid email address. This is done in two steps:

  1. Request email confirmation

Swift
Objective-C
Java
Javascript
.NET
Swift
let serverURL = URL(string: "https://foo.us1.realm.cloud.io")
let email = "user@email.com"
SyncUser.requestEmailConfirmation(forAuthServer: serverURL, userEmail: email) { error in
if error {
// something went wrong
}
}
Objective-C
NSURL *serverURL = [NSURL URLWithString:@"https://foo.us1.realm.cloud.io"];
NSString *email = @"user@email.com";
[RLMSyncUser requestEmailConfirmationForAuthServer:serverURL userEmail:email completion:^(NSError *error) {
if (error) {
// Something went wrong
}
}];
Java
SyncUser.requestEmailConfirmationAsync("user@email.com", "https://foo.us1.realm.cloud.io", new SyncUser.Callback<Void>() {
@Override
public void onSuccess(Void result) {
}
@Override
public void onError(ObjectServerError error) {
}
});
Javascript
Realm.Sync.User.requestEmailConfirmation('https://foo.us1.realm.cloud.io', 'user@email.com').then(() => {
// query sent successfully.
}).catch((error) => {
// an error has occurred
});
.NET
var serverUri = new Uri("https://foo.us1.realm.cloud.io");
await User.RequestEmailConfirmationAsync(serverUri, "user@email.com");
  1. Complete the email confirmation using the token sent in email, this can be completed by clicking on the link inside the email or via the API if we manage to extract the token from the email (using deep linking for instance):

Swift
Objective-C
Java
Javascript
.NET
Swift
let serverURL = URL(string: "https://foo.us1.realm.cloud.io")
let token = "resetToken"
SyncUser.confirmEmail(forAuthServer: serverURL, token: token) { error in
if error {
// something went wrong
}
}
Objective-C
NSURL *serverURL = [NSURL URLWithString:@"https://foo.us1.realm.cloud.io"];
NSString *token = @"confirmation_token";
[RLMSyncUser confirmEmailForAuthServer:serverURL token:token completion:^(NSError *error) {
if (error) {
// Something went wrong
}
}];
Java
SyncUser.confirmEmailAsync("confirmation_token", "https://foo.us1.realm.cloud.io", new SyncUser.Callback<Void>() {
@Override
public void onSuccess(Void result) {
}
@Override
public void onError(ObjectServerError error) {
}
});
Javascript
Realm.Sync.User.confirmEmail('https://foo.us1.realm.cloud.io', 'confirmation_token').then(() => {
// query sent successfully.
}).catch((error) => {
// an error has occurred
});
.NET
var serverUri = new Uri("https://foo.us1.realm.cloud.io");
await User.ConfirmEmailAsync(serverUri, "confirmation_token");

Nickname Authentication

Nickname authentication is meant to be used strictly for prototyping purposes. It allows you to register and authenticate a user by providing only a nickname (no password).

The Nickname provider is not secure and should never be enabled in production deployments. It's only meant to be used during development.

Client Authentication

Swift
Objective-C
Java
Javascript
.Net
Swift
let auth_url = URL(string: "https://myinstance.cloud.realm.io")!
let creds = SyncCredentials.nickname("nickname", isAdmin: true)
SyncUser.logIn(with: creds, server: auth_url, onCompletion: { [weak self](user, err) in
if let _ = user {
// User is logged in
} else if let error = err {
fatalError(error.localizedDescription)
}
}
Objective-C
NSURL *authURL = [NSURL URLWithString:@"https://myinstance.cloud.realm.io"]
RLMSyncCredentials *nicknameCredentials = [RLMSyncCredentials credentialsWithNickname:@"nickname" isAdmin:YES];
[RLMSyncUser logInWithCredentials:creds authServerURL:authUrl onCompletion:^(RLMSyncUser *syncUser, NSError *error) {
// ...
});
}];
Java
String authURL = "https://myinstance.cloud.realm.io";
SyncCredentials credentials = SyncCredentials.nickname("my-nickname", false);
SyncUser.login(credentials, authUrl, new SyncUser.Callback<SyncUser>() {
@Override
public void onSuccess(SyncUser user) {
// User is logged
}
@Override
public void onError(ObjectServerError error) {
// Handle error
}
});

The last boolean indicates if the user created should be an admin user or not.

Javascript
const authUrl = 'https://myinstance.cloud.realm.io';
let creds = Realm.Sync.Credentials.nickname('nickname');
Realm.Sync.User.login(authUrl, creds).then(user => {
// user is logged in
// do stuff ...
}).catch(error => {
// an auth error has occurred
});
.Net
var authUrl = new Uri("https://myinstance.cloud.realm.io");
var credentials = Credentials.Nickname("my-nickname");
var user = await User.LoginAsync(credentials, authUrl);

Enable/Disable

Cloud
Self-Hosted
Cloud
Self-Hosted

By default the Nickname provider is enabled when creating a project via ros init.

For more details on how to enable or disable this provider, head over to our server docs.

Anonymous Authentication

To create a synchronized Realm for a user without requiring credentials - e.g. in an e-commerce application where any disruption leads to user churn - the Realm Object Server exposes an anonymous authentication provider that requires no payload, and creates a new user for every request (which means that you must use the built-in client-side user caching to avoid resetting the app state on every launch).

Client Authentication

Swift
Objective-C
Java
Javascript
.Net
Swift
let auth_url = URL(string: "https://myinstance.cloud.realm.io")!
let creds = SyncCredentials.anonymous()
SyncUser.logIn(with: creds, server: auth_url, onCompletion: { [weak self](user, err) in
if let _ = user {
// User is logged in
} else if let error = err {
fatalError(error.localizedDescription)
}
}
Objective-C
NSURL *authURL = [NSURL URLWithString:@"https://myinstance.cloud.realm.io"]
RLMSyncCredentials *anonCredentials = [RLMSyncCredentials anonymousCredentials];
[RLMSyncUser logInWithCredentials:creds authServerURL:authUrl onCompletion:^(RLMSyncUser *syncUser, NSError *error) {
// ...
});
}];
Java
String authURL = "https://myinstance.cloud.realm.io";
SyncCredentials credentials = SyncCredentials.anonymous();
SyncUser.login(credentials, authUrl, new SyncUser.Callback<SyncUser>() {
@Override
public void onSuccess(SyncUser user) {
// User is logged
}
@Override
public void onError(ObjectServerError error) {
// Handle error
}
});
Javascript
const authUrl = 'https://myinstance.cloud.realm.io';
let creds = Realm.Sync.Credentials.anonymous();
Realm.Sync.User.login(authUrl, creds).then(user => {
// user is logged in
// do stuff ...
}).catch(error => {
// an auth error has occurred
});
.Net
var authUrl = new Uri("https://myinstance.cloud.realm.io");
var credentials = Credentials.Anonymous();
var user = await User.LoginAsync(credentials, authUrl);

Enable / Disable

Cloud
Self-Hosted
Cloud

Anonymous authentication is enabled by default in Cloud-hosted Realm instances.

To enable or disable anonymous authentication, go to the Settings menu in your instance in the cloud portal:

Self-Hosted

By default, the AnonymousAuthProvider is enabled when creating a project via ros init.

For more details on how to enable or disable this provider, head over to our server docs.