Navigation

Custom Function Authentication

Overview

The Custom Function authentication provider allows you to use a Stitch function to implement your own user authentication logic or flexibly integrate an external authentication system. You can use the Custom Function provider to integrate with any authentication system as long as the system maintains a unique ID value for each user.

The authentication function is a Stitch function that you define to handle authentication logic for users that log in with the Custom Function provider. You can use the function to coordinate with an external authentication system and/or use data that you store in MongoDB to identify and authenticate users.

Validate and Authenticate Custom Function Users

Stitch does not perform any data validation or authentication checks for the Custom Function provider. Make sure that you validate incoming data and that your authentication system performs appropriate authentication checks, such as requiring a password, two factor authentication, or a single sign-on token.

Configure Custom Function Authentication

1
2

Enable the Provider

To create new users and allow them to log in, you must enable the Custom Function provider. To do so, set the Provider Enabled toggle to On.

3

Define the Authentication Function

The authentication function must return a string ID value that uniquely identifies the user. Stitch uses this value to lookup an existing Stitch user and automatically creates a new user if it does not match an existing user. If the function does not return a string, Stitch throws an error and does not create or authenticate a user.

Stitch Generates New User ID Values

The ID value that you return from the authentication function is not the internal Stitch user id (i.e. the value that %%user and context.user resolve to). Stitch automatically generates a unique id for Custom Function users when it creates them.

To define a new authentication function, click the Function dropdown and select New Function.

Example

An application implements a Custom Function authentication provider that stores user data in the app.users MongoDB collection. The app lets users log in by specifying their username but does not require a password or any other type of authentication.

The appication’s authentication function queries the users collection for an existing user with the specified username. If the user already exists, the function returns their stored id value. If the user does not exist, the function stores a new user document in the collection and returns that document’s id value.

exports = async function(loginPayload) {
  // Get a handle for the app.users collection
  const users = context.services
    .get("mongodb-atlas")
    .db("app")
    .collection("users");

  // Parse out custom data from the FunctionCredential
  const { username } = loginPayload;

  // Query for an existing user document with the specified username
  const user = await users.findOne({ username });

  if (user) {
    // If the user document exists, return its unique ID
    return user._id.toString();
  } else {
    // If the user document does not exist, create it and then return its unique ID
    const result = await users.insertOne({ username });
    return result.insertedId.toString();
  }
};
4

Deploy the Updated Application

Once you have written and saved the authentication function, you can make Custom Function authentication available to client applications by deploying your application. To deploy a draft application from the Stitch UI:

  1. Click Deploy in the left-hand navigation
  2. Find the draft in the deployment history table and then click Review & Deploy Changes.
  3. Review the diff of changes and then click Deploy.

Once the application successfully deploys, you will be able to create and log in as a Custom Function user from a client application.

1

Export Your Stitch Application

You can set up and enable the Custom Function authentication provider through Stitch CLI or automatic GitHub deployment. To configure the provider, you need the latest version of the application directory for your application.

You can export your application from the Export tab of the Settings page in the Stitch UI, or by running the following command from an authenticated instance of stitch-cli:

stitch-cli export --app-id=<App ID>
2

Define the Authentication Function

The authentication function must return a string ID value that uniquely identifies the user. Stitch uses this value to lookup an existing Stitch user and automatically creates a new user if it does not match an existing user. If the function does not return a string, Stitch throws an error and does not create or authenticate a user.

Stitch Generates New User ID Values

The ID value that you return from the authentication function is not the internal Stitch user id (i.e. the value that %%user and context.user resolve to). Stitch automatically generates a unique id for Custom Function users when it creates them.

To create the authentication function, write the function code and then follow the steps in Define a Function to add it to your application.

Example

An application implements a Custom Function authentication provider that stores user data in the app.users MongoDB collection. The app lets users log in by specifying their username but does not require a password or any other type of authentication.

The application’s authentication function queries the users collection for an existing user with the specified username. If the user already exists, the function returns their stored id value. If the user does not exist, the function stores a new user document in the collection and returns that document’s id value.

exports = async function(loginPayload) {
  // Get a handle for the app.users collection
  const users = context.services
    .get("mongodb-atlas")
    .db("app")
    .collection("users");

  // Parse out custom data from the FunctionCredential
  const { username } = loginPayload;

  // Query for an existing user document with the specified username
  const user = await users.findOne({ username });

  if (user) {
    // If the user document exists, return its unique ID
    return user._id.toString();
  } else {
    // If the user document does not exist, create it and then return its unique ID
    const result = await users.insertOne({ username });
    return result.insertedId.toString();
  }
};
3

Add a Provider Configuration File

To configure the Custom Function authentication provider, create a new authentication provider configuration file named custom-function.json in the auth_providers directory and set the value of config.authFunctionName the name of the authentication function:

/auth_providers/custom-function.json
{
    "name": "custom-function",
    "type": "custom-function",
    "config": {
      "authFunctionName": "<Authentication Function Name>"
    },
    "disabled": false
}
4

Deploy the Updated Application

Once you have created the authentication function and configured the provider, you can make Custom Function authentication available to client applications by deploying your application.

To deploy a draft application with Stitch CLI:

stitch-cli import

To deploy a draft application with automatic GitHub deployment:

git add functions/<Authentication Function Name>
git add auth_providers/custom-function.json
git commit -m "Configure and Enable Custom Function Authentication"
git push

Once the application successfully deploys, you will be able to create a user and log in with the Custom Function provider from a client application.

Use Custom Function Authentication

Authenticate a User

To log a user in to your app with the Custom Function authentication provider, call StitchAuth.loginWithCredential() with an instantiated FunctionCredential that contains any data required for authentication.

const credential = new FunctionCredential({ someField: "<someValue>" });

Stitch.defaultAppClient.auth.loginWithCredential(credential)
  .then(authedUser => {
    console.log(`logged in with custom function auth as user ${authedUser.id}`)
  })
  .catch(err => {
    console.error(`failed to log in with custom function auth: ${err}`)
  })

To log a user in to your app with the Custom Function authentication provider, call StitchAuth.loginWithCredential() with an instantiated FunctionCredential that contains any data required for authentication.

FunctionCredential credential = FunctionCredential(Document("someField", "<someValue>"));

Stitch.getDefaultAppClient().getAuth().loginWithCredential(credential)
  .addOnCompleteListener(new OnCompleteListener<StitchUser>() {
    @Override
    public void onComplete(@NonNull final Task<StitchUser> task) {
      if (task.isSuccessful()) {
        Log.d("stitch", "logged in with custom function auth as user " + task.getResult().id);
      } else {
        Log.e("stitch", "failed to log in with custom function auth:", task.getException());
      }
    }
  });

To log a user in to your app with the Custom Function authentication provider, call StitchAuth.login(withCredential:_:) with an instantiated FunctionCredential that contains any data required for authentication.

let credential = FunctionCredential.init(payload: ["someField": "<someValue>"])

Stitch.defaultAppClient!.auth.login(withCredential: credential) { result in
  switch result {
  case .success(let user):
    print("logged in with custom function auth as user \(user.id)")
  case .failure(let error):
    print("failed to log in with custom function auth: \(error)")
}