Docs Menu
Docs Home
/ /
Atlas Device SDKs
/ /

Authenticate Users - Node.js SDK

On this page

  • Log In
  • User Sessions
  • Anonymous User
  • Email/Password User
  • API Key User
  • Custom JWT User
  • Custom Function User
  • Facebook User
  • Google User
  • Apple User
  • Offline Login
  • Get a User Access Token
  • Refresh Token Expiration
  • Log a User Out

Realm provides an API for authenticating users into an App with any enabled authentication provider. Instantiate a Credentials object and pass it to the app.login() method to authenticate a user login and create a User object.

Atlas App Services manages sessions with access tokens and refresh tokens. Client SDKs supply the logic to manage tokens, and provide them with requests.

Tip

See also:

The Anonymous provider allows users to log in to your application with temporary accounts that have no associated information.

To log in, create an anonymous credential and pass it to App.logIn():

The email/password authentication provider allows users to log in to your application with an email address and a password.

To log in, create an email/password credential with the user's email address and password and pass it to App.logIn():

The API key authentication provider allows server processes to access your app directly or on behalf of a user.

To log in with an API key, create an API Key credential with a server or user API key and pass it to App.logIn():

The Custom JWT authentication provider allows you to handle user authentication with any authentication system that returns a JSON web token.

To log in, create a Custom JWT credential with a JWT from the external system and pass it to App.logIn():

The Custom Function authentication provider allows you to handle user authentication by running a function that receives a payload of arbitrary information about a user.

To log in with the custom function provider, create a Custom Function credential with a payload object and pass it to App.logIn():

The Facebook authentication provider allows you to authenticate users through a Facebook app using their existing Facebook account.

Important

Enable the Facebook Auth Provider

To log a user in with their existing Facebook account, you must configure and enable the Facebook authentication provider for your application.

Important

Do Not Store Facebook Profile Picture URLs

Facebook profile picture URLs include the user's access token to grant permission to the image. To ensure security, do not store a URL that includes a user's access token. Instead, access the URL directly from the user's metadata fields when you need to fetch the image.

You can use the official Facebook SDK to handle the user authentication and redirect flow from a client application. Once authenticated, the Facebook SDK returns an access token that you can send to your Node.js app and use to finish logging the user in to your app.

// Get the access token from the Facebook SDK
const { accessToken } = FB.getAuthResponse();
// Define credentials with the access token from the Facebook SDK
const credentials = Realm.Credentials.facebook(accessToken);
// Log the user in to your app
await app.logIn(credentials);

The Google authentication provider allows you to authenticate users through a Google project using their existing Google account.

Note

Enable the Google Auth Provider

To authenticate a Google user, you must configure the Google authentication provider. You must enable OpenID Connect to use the Google Authentication Provider with the Node.js SDK.

To set up your App for Google User authentication in your App configuration:

  1. In the Google Cloud Platform console, create an OAuth 2.0 client ID of type "Web application".

  2. Configure your backend App to use that client ID and the associated client secret.

  3. Enable OpenID Connect on the backend.

Use the official Google Auth Library for Node.js to handle the user authentication and redirect flow from a Node.js client application:

  1. Install the Realm and Google APIs npm packages.

    npm install realm googleapis
  2. Import the packages into your project.

    const Realm = require("realm");
    const { google } = require("googleapis");
  3. Create configuration for Google OAuth 2.0 client and Realm.

    // Configure and instantiate Google OAuth2.0 client
    const oauthConfig = {
    client_id: GOOGLE_CLIENT_ID,
    project_id: GOOGLE_PROJECT_ID,
    auth_uri: "https://accounts.google.com/o/oauth2/auth",
    token_uri: "https://oauth2.googleapis.com/token",
    auth_provider_x509_cert_url: "https://www.googleapis.com/oauth2/v1/certs",
    client_secret: GOOGLE_CLIENT_SECRET,
    redirect_uris: [`${BASE_URL}/auth/google/callback`],
    JWTsecret: "secret",
    scopes: [
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/userinfo.profile",
    "openid",
    // any other scopes you might require. View all here - https://developers.google.com/identity/protocols/oauth2/scopes
    ],
    };
    const OAuth2 = google.auth.OAuth2;
    const oauth2Client = new OAuth2(
    oauthConfig.client_id,
    oauthConfig.client_secret,
    oauthConfig.redirect_uris[0]
    );
    // Instantiate Realm app
    const realmApp = new Realm.App({
    id: REALM_APP_ID,
    });
  4. Generate an OAuth login link, and pass it to the application client.

    // generate OAuth 2.0 log in link
    const loginLink = oauth2Client.generateAuthUrl({
    access_type: "offline", // Indicates that we need to be able to access data continuously without the user constantly giving us consent
    scope: oauthConfig.scopes,
    });
  5. Process the request from the the Google authentication server, which includes an access code in the query string using the Google OAuth 2.0 client's getToken() method. In the callback function, sign in to your App using the id_token.

    // Get Google token and use it to sign into Realm
    oauth2Client.getToken(authCodeFromQueryString, async function (
    error,
    token
    ) {
    if (error) return errorHandler(error);
    try {
    const credential = Realm.Credentials.google({
    idToken: token.id_token,
    });
    const user = await realmApp.logIn(credential);
    console.log("signed in as Realm user", user.id);
    } catch (error) {
    errorHandler(error);
    }
    });

Example

Authenticate with Google on a Node.js Server

Refer to the code for an example Node.js server that implements Sign in With Google. All of the Google OAuth 2.0 implementation is in the server.js file.

The example uses Express for routing and the Google Auth Library for Node.js.

You might want to authenticate with Google on a Node.js server to perform server-side operations on behalf of a user, like call an Atlas Function with a user's credentials.

The Apple authentication provider allows you to authenticate users through Sign-in With Apple.

Note

Enable the Apple Auth Provider

To authenticate an Apple user, you must configure the Apple authentication provider.

You can use the official Sign in with Apple JS SDK to handle the user authentication and redirect flow from a client application. Once authenticated, the Apple JS SDK returns an ID token that you can send to your Node.js app and use to finish logging the user in to your app.

// Get the ID token from the Apple SDK
const { id_token } = await AppleID.auth.signIn();
// Define credentials with the ID token from the Apple SDK
const credentials = Realm.Credentials.apple(id_token);
// Log the user in to your app
const user = await app.logIn(credentials);

Tip

If you get a Login failed error saying that the token contains an invalid number of segments, verify that you're passing a UTF-8-encoded string version of the JWT.

When your Realm application authenticates a user, it caches the user's credentials. You can check for existing user credentials to bypass the login flow and access the cached user. Use this to open a realm offline.

Note

Initial login requires a network connection

When a user signs up for your app, or logs in for the first time with an existing account on a client, the client must have a network connection. Checking for cached user credentials lets you open a realm offline, but only if the user has previously logged in while online.

// Log user into your App Services App.
// On first login, the user must have a network connection.
const getUser = async () => {
// If the device has no cached user credentials, log in.
if (!app.currentUser) {
const credentials = Realm.Credentials.anonymous();
await app.logIn(credentials);
}
// If the app is offline, but credentials are
// cached, return existing user.
return app.currentUser!;
};

To learn how to use the cached user in the Sync Configuration and access a realm while offline, read the Open a Synced Realm While Offline docs.

When a user logs in, Atlas App Services creates an access token for the user that grants them access to your App. The Realm SDK automatically manages access tokens, refreshes them when they expire, and includes a valid access token for the current user with each request. Realm does not automatically refresh the refresh token. When the refresh token expires, the user must log in again.

If you send requests outside of the SDK, you need to include the user's access token with each request and manually refresh the token when it expires.

You can access and refresh a logged in user's access token in the SDK from their Realm.User object, as in the following example:

Refresh tokens expire after a set period of time. When the refresh token expires, the access token can no longer be refreshed and the user must log in again.

If the refresh token expires after the realm is open, the device will not be able to sync until the user logs in again. Your sync error handler should implement logic that catches a token expired error when attempting to sync, then redirect users to a login flow.

For information on configuring refresh token expiration, refer to Manage User Sessions in the App Services documentation.

To log any user out, call the User.logOut() on their user instance.

Warning

When a user logs out, you can no longer read or write data in any synced realms that the user opened. As a result, any operation that has not yet completed before the initiating user logs out cannot complete successfully and will likely result in an error. Any data in a write operation that fails in this way will be lost.

// Log out the current user
await app.currentUser?.logOut();
← Create and Delete Users