GenAuth DocsDocuments
Concepts
User Guide
Development Integration
AgentAuth
Metadata
Development Integration
Multi-tenant (beta)
Console Documentation
Multi-tenant Console
Tenant Console
Saas Application Demo
Concepts
User Guide
Development Integration
AgentAuth
Metadata
Development Integration
Multi-tenant (beta)
Console Documentation
Multi-tenant Console
Tenant Console
Saas Application Demo
Old version
User Guide
  • Quick Start

  • Authentication

  • Access Control

  • Authorization

  • Adaptive MFA

  • User Account Management

  • User Directory Management

  • Applications

  • Become a Federation Authentication Identity Provider

  • Connect External Identity Providers (IdP)

  • WeChat Ecosystem Full Scenario Capabilities

  • Migrate Users to GenAuth

  • Security Settings

  • Branding

  • Automation

  • Audit Logs

  • Setting

  • FAQ

¶ Configure database connection and write scripts

Update time: 2025-07-23 07:34:21
Edit

You can customize database authentication users. To do this, you need to configure database connection, write database operation scripts, and configure environment variables (optional).

Please make sure that your database has some fields required for GenAuth user profiles, such as id, email, photo, nickname, username, phone, etc. For details, please see GenAuth User Profile Detailed Fields and Their Interpretations to understand the GenAuth user profile Schema.

GenAuth supports direct connection to the following mainstream databases and custom Web Services:

  • MySQL
  • PostgreSQL
  • MongoDB
  • Web Services: You can encapsulate the database into a service without directly exposing the database connection. For example, you can encapsulate the authentication operation into an API: https://mydomain.com/auth.

If the service you access in the script is configured with a firewall, please make sure it is open to the following IP addresses: 140.179.19.50, 52.80.250.250. You can also dynamically obtain the external IP address of the GenAuth server through the following API: https://core.genauth.ai/api/system/public-ips (opens new window).

¶ Enable custom database connection

Once the custom database is enabled, it will take effect immediately. Before you write a custom script, users will be prompted with an error similar to Please implement the Login script for this database connection when trying to log in. This is an error prompted by the default script. Please modify the script or temporarily close the custom database connection.

Log in to the GenAuth console (opens new window), and on the Connect Identity Source - Custom Database page, click the Open button:

¶ Select scenario

Custom databases have two different modes, and you can choose the appropriate mode according to your business needs:

  • Lazy migration of users: This mode of migrating users is called lazy migration. In simple terms, the principle is as follows: At the beginning, all the original user data is in your database. When the user tries to log in to GenAuth for the first time, GenAuth will search and verify the user in your database through the custom database script you configured. If successful, the user will be migrated to GenAuth; when the user logs in for the second time, the GenAuth database will be used to verify it; when all users have logged in at least once, it means that the migration task to the cloud is completed. For details, please see: Use a custom database to implement lazy user migration (opens new window).
  • Use a custom database completely: In this mode, user data is always stored in your database, and GenAuth will never save your user data. In order for the system to work properly, you need to implement a complete user add, delete, modify and query script.

¶ Configure database connection information

Next, fill in the database connection information. You can choose Connection URI and Programmatic:

¶ Connection URI format

Connection URI is generally a URI in the form of protocol://username:password@host:port/database, such as postgres://postgres:postgres@localhost:5432/database-name. You can reference it in the script through the global variable env.DB_CONNECTION_URI, as shown below:

const { Client } = require("pg");

const client = new Client({
  connectionString: env.DB_CONNECTION_URI,
});
await client.connect();

¶ Programmatic Form

This mode specifies the database host, port, username, password, and database name respectively, which can be referenced in the script through the global variables env.DB_HOST, env.DB_PORT, env.DB_USERNAME, env.DB_PASSWORD, and env.DB_DATABASE, as shown below:

const { Client } = require("pg");
const client = new Client({
  host: env.DB_HOST,
  port: env.DB_PORT,
  user: env.DB_USERNAME,
  password: env.DB_PASSWORD,
  database: env.DB_DATABASE,
});
await client.connect();

¶ Write database operation scripts

We currently provide MySQL, PostgreSQL, MongoDB, Custom service four types of templates, you can write corresponding scripts as needed.

When you choose Migrate user data to GenAuth (LAZY_MIGRATION) mode, you need to write two functions in total:

  • Login: This script will be executed when the user tries to log in. If the user is not synchronized to the GenAuth database, the user account and password will be checked according to the script you filled in.
  • Find user: This script will be executed when the user tries to register. If the script returns the user identity information, the user will be prompted that the user already exists and the registration failed.

When you choose Use your own database completely (CUSTOM_USER_STORE) mode, you need to write the following functions in total:

  • Login: This script will be executed when the user tries to log in. If the user is not synchronized to the GenAuth database, the user account and password will be checked according to the script you filled in.
  • Accurately find user: This script will be executed when the user tries to register. If the script returns the user identity information, the user will be prompted that the user already exists and the registration failed.
  • Fuzzy search for users: This script will be called when the administrator uses the console or API to fuzzily search for users.
  • Create user: This script will be executed when the user registers or creates a user using the API and console. You need to save the user information to your own database.
  • Modify user information: This script will be executed when the administrator modifies the user information or the user modifies the user information himself.
  • Delete user: This script will be executed when the administrator deletes the user account using the console or API.
  • Get user list: This script will be executed when the administrator uses the console or API to get the user list. The data required by this interface needs to include the total number of users and the user list of the current page.
  • Verify password: This script will be executed when the user tries to reset the password and verify the original password.
Select script name
登录
Loading...

This script will be executed when the user tries to log in. If the user is not synchronized to the GenAuth database, the user account and password will be checked according to the script you filled in. This script is required in both lazy migration of users and fully using a custom database mode.

¶ Function definition

The login function is defined as follows:

async function login(query, password, context) {
  // The first argument query contains following contents:
  // query.email
  // query.username
  // query.phone

  // The second argument password is user's password in plain text format.

  // The Second argument context contains information about the authentication context.
  // see http://core.genauth.ai/connections/custom-db/config-custom-db-connection.html for more information.

  // This script should retrieve a user profile from your existing database,
  // without authenticating the user.

  // It is used to check if a user exists before executing flows that do not
  // require authentication (signup and password reset).
  //
  // There are three ways this script can finish:
  // 1. A user was successfully found, and password is valid, The profile should be in the following
  // format: https://docs.authing.co/user/profile.html .
  //    return profile
  // 2. A user was not found
  //    throw new Error('User not exists!');
  // 3. A user was found, but password is not valid
  //    throw new Error('Password is not valid!');
  // 4. Something went wrong while trying to reach your database:
  //    throw new Error("my error message")

  const msg = "Please implement the Login script for this database connection";
  throw new Error(msg);
}
ParameterTypenullableDescription
queryobjectfalseQuery conditions
query.emailstringtrueEmail address. This parameter is not empty when the user logs in using an email address.
query.phonestringtruePhone number. This parameter is not empty when the user logs in using a phone number.
query.usernamestringtrueUsername. This parameter is not empty when the user logs in using a username.
passwordstringfalsePlain text password. It is strongly recommended to use bcrypt to encrypt user passwords. See below for details.
contextobjecttrueRequest context context

The context contains the following information:

Attribute nameTypeDescription
userPoolIdstringUser pool ID
userPoolNamestringUser pool name
userPoolMetadataobjectUser pool configuration information
appIdstringID of the current user. **You can use appId to distinguish the application source of the user request. **
appNamestringThe name of the current application
appMetadataobjectConfiguration information of the current application
applicationstringUser pool ID
requestobjectDetailed information of the current request, including:
ip: Client IP
geo: Client geographic location resolved by IP
body: Request body

¶ Return data convention

¶ User exists and password is correct

When the user exists and the password is correct, you need to return the user's user information to GenAuth. For the detailed format of the user information, please refer to: User Profile Detailed Fields . Example:

async function login(query, password, context) {
  // Implement your logic here
  return {
    id: 1, // must not empty
    email: "test@example.com",
    emailVerified: true,
    nickname: "Nick",
    photo: "",
  };
}

¶ User does not exist

When the user does not exist, you need to throw an error directly (the error message can be freely defined), for example:

async function login(query, password, context) {
  // Implement your logic here
  throw new Error("User not exists");
}

¶ User exists but password is incorrect

When the user exists but the password is incorrect, you need to throw an error directly (the error message can be freely defined), for example:

async function login(query, password, context) {
  // Implement your logic here
  throw new Error("User not exists");
}

¶ Other abnormal errors

When encountering other abnormal errors, you can catch the error and return a more friendly error prompt, for example:

async function login(query, password, context) {
  try {
    // Implement your logic here
  } catch (error) {
    throw new Error("Something went wrong ...");
  }
}

¶ Best Practices

¶ Provide friendly error prompts

When encountering unknown errors, we recommend throwing a standard Error object, which GenAuth will capture and eventually return to the end user. For example: throw new Error("My nice error message"), you can see the error log in the Log History of the custom database.

¶ Encrypt passwords with bcrypt

We recommend using bcrypt to encrypt and save user data, such as:

const bcrypt = require("bcrypt");
const hashedPassword = await bcrypt.hash("passw0rd", await bcrypt.genSalt(10));

Verify that the password is correct:

const bcrypt = require("bcrypt");
const valid = await bcrypt.compare("passw0rd", user.password);

¶ Disconnect database connection at the end of the function

Please remember to close the connection to the database when the script is executed, such as calling client.end(). For example, you can execute it in try/finally to ensure that it will always be executed:

try {
  const result = await client.query("YOUR QUERY");
} finally {
  // NOTE: always call `client.end()` here to close the connection to the database
  client.end();
}

¶ Example function

Take postgres database as an example, there are the following points:

  • You can get the database connection string through env.DB_CONNECTION_URI to create a database connection.
  • Dynamically create a query statement based on the query conditions passed in query (query.email, query.username, query.phone may all be empty, but not empty at the same time).
  • If the user does not exist, throw an exception directly, and the error message is User not exists!.
  • If the user exists but the password is incorrect, throw an exception directly, and the error message is Password is not valid!.
  • Finally, return the user information in the specified format. For the detailed format of the user information, please see: User Profile Detailed Fields.
  • Call client.end() in try/finally to disconnect the database connection.
async function login(query, password, context) {
  // The first argument query contains following contents:
  // query.email
  // query.username
  // query.phone
  const { email, username, phone } = query;

  // The second argument password is user's password in plain text format.

  // The last argument context contains information about the authentication context.
  // see http://core.genauth.ai/connections/custom-db/config-custom-db-connection.html for more information.

  // This example uses the "pg" library
  // more info here: https://github.com/brianc/node-postgres
  const { Client } = require("pg");

  const client = new Client({
    connectionString: env.DB_CONNECTION_URI,
  });

  // Or you can:
  // const client = new Client({
  //   host: env.DB_HOST,
  //   port: env.DB_PORT,
  //   user: env.DB_USERNAME,
  //   password: env.DB_PASSWORD,
  //   database: env.DB_DATABASE,
  // });

  await client.connect();

  // Use bcrypt to validate password
  // more info here: https://github.com/kelektiv/node.bcrypt.js
  const bcrypt = require("bcrypt");

  // Building query parameters
  const queries = [];
  const parameters = [];
  let index = 1;
  if (email) {
    queries.push(`email = $${index}`);
    parameters.push(email);
    index += 1;
  }
  if (phone) {
    queries.push(`phone = $${index}`);
    parameters.push(phone);
    index += 1;
  }
  if (username) {
    queries.push(`username = $${index}`);
    parameters.push(username);
    index += 1;
  }

  const QUERY = `SELECT * FROM users WHERE ${queries.join(" OR ")}`;

  try {
    const result = await client.query(QUERY, parameters);
    if (result.rows.length === 0) {
      throw new Error("User not exists!");
    }
    const user = result.rows[0];

    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
      throw new Error("Password is not valid!");
    }

    return {
      id: user.id,
      email: user.email,
      phone: user.phone,
      username: user.username,
      photo: user.photo,
      nickname: user.nickname,
      token: user.token,
      emailVerified: user.email_verified,
      phoneVerified: user.phone_verified,
      loginsCount: user.logins_count,
      lastIp: user.last_ip,
      gender: user.gender,
      address: user.address,
      company: user.company,
      birthdate: user.birthdate,
      website: user.website,
    };
  } catch (error) {
    throw new Error(`Execute query failed: ${error.message}`);
  } finally {
    // NOTE: always call `client.end()` here to close the connection to the database
    client.end();
  }
}

¶ Test database script

We provide developers with an online database for quick testing. You can use this database for quick testing. Click here (opens new window) to access.

The database is free for all users. The database connection information is postgres://postgres:postgres_root_local@47.74.20.164:31000/custom-db-connection. You can create a test user or use the sample user in the list.

After configuring the Connection URI, click Save and then click the Debug button at the bottom.

Fill in a user in the user list of the sample user pool in the pop-up form:

Click the Test button, and you should see the relevant success prompt.

  • Enable custom database connection
  • Select scenario
  • Configure database connection information
  • Write database operation scripts
  • Test database script

User identity management

Integrated third-party login
Customized authentication process

Enterprise internal management

Single sign-on
Multi-factor authentication
Permission management

Developer

Development Documentation
GitHub (opens new window)

Company

official@genauth.ai
16th Floor, Building B, Beichen Century Center, Chaoyang District, Beijing (Total)
Room 406, 4th Floor, Block B, No. 200, Tianfu Fifth Street, High-tech Zone, Chengdu (Branch)

© Beijing Steamory Technology Co., Ltd.