Migration Tutorial

Overview

This tutorial shows you how to migrate user data from a single existing user database into FusionAuth.

In addition to the example code provided here, you may find example code relevant to your migration in our Import Scripts GitHub repository.

You also may be interested in the general migration guide which covers the topic in more depth.

In many cases, you’ll have an existing user database in MySQL, Mongo, or another similar database. In many cases, your user table (or objects) will contain the user information that your application needs in columns or properties. Here’s an example table structure for a relational database for a user:

CREATE TABLE user (
  id INTEGER NOT NULL AUTO_INCREMENT,
  name VARCHAR(255) NULL,
  email VARCHAR(255) NOT NULL,
  password VARCHAR(255) NOT NULL,
  profile_picture_url VARCHAR(255) NOT NULL,
  profile_description TEXT,
  role VARCHAR(255) NOT NULL,
  ...
);

This data will be migrated into FusionAuth by exporting it from the existing database and then importing it into FusionAuth.

Password Encryption

The first step of the migration process is to determine how passwords are hashed in your current user database. If they are not hashed, you can skip this step and FusionAuth will automatically hash them for you during the import process. Once you have determined the hashing algorithm used in your existing database, you will need to write a password hashing plugin. The documentation for writing plugins and a custom password hasher are located here:

Create the Applications

Next, you will need to create all of the Applications in FusionAuth that users will be registered with. For example, you might have a website and a forum that are both using the same user database. In this case, you will need to create a FusionAuth Application for your website and another Application for your forum.

Once you have created the Applications, store the IDs for each so that you can use them during the import process.

For our example above, we will assume only a single Application called Website with a UUID of 79a34811-d627-4751-bb9c-9ab148ab8dc9.

Determine FusionAuth Data Locations

FusionAuth has a number of properties on the base User object. You can read about those properties in the Create a User API section. Your existing database might have additional user properties that you need to migrate. These can be stored in the data object inside the User object. This object is also described in Create a User API section. The data object allows completely free-form data to be stored.

Additionally, each user can have 0 or more registrations created during the import. Registrations are used to control access to your application(s) and also provide authorization via roles for each application. Registrations can also have a data object to store additional attributes for each user. You will need to determine if you want to store your additional user data on the base User object or the Registration object. The choice might depend on if the data is used globally for all of your applications or just in a single application.

For our example above, we’ll place all of our extra data in a Registration object for our Website Application.

Export/Import the Existing User Data

The simplest way to migrate the data from an existing database to FusionAuth is to write a program or script that reads records from the existing database and batch imports them into FusionAuth. We won’t write a complete script here, but here is some pseudo code you can use when building your script:

Migration Script Example

def existingUser
def importUsers = []
while ((existingUser = readNextUser()) != null) {
  def fusionauthUser = {
    fullName: existingUser.name,
    email: existingUser.email,
    password: existingUser.password,
    encryptionScheme: "my-custom-encryption-scheme",
    imageURL: existingUser.profilePicture,
    registrations: [
      {
        applicationID: "79a34811-d627-4751-bb9c-9ab148ab8dc9",
        data: {
          profileDescription: existingUser.profileDescription
        }
        roles: [
          existingUser.role
        ]
      }
    ]
  }

  importUsers.add(fusionauthUser)
}

FusionAuthClient client = new FusionAuthClient("http://localhost:9011", "my-api-key")
client.importUsers(new ImportRequest(importUsers))

This code reads each user from the existing database, creates a new FusionAuth User object from the existing user data, and then bulk imports all of the users into FusionAuth in one request. Generally speaking this process works for small databases (under 10,000 users). If you have a large database, you will want to import users in blocks of 1,000 or 10,000 to avoid crashing FusionAuth.

This example uses a FusionAuthClient to perform the import. You may also call the Import Users API directly if you prefer (or if a FusionAuthClient is not available for your language of choice).