Automatically log in a user after Gravity Forms Registration

If you want to automatically log in a user, there are two primary methods in WordPress. For this article, we’re doing this in the context of automatic login with a Gravity Forms form and the Registration addon. You should have installed both Gravity Forms and the User Registration addon.

Login via Registration hook and wp_signon()

There is a “standard” way to automatically login users which is almost all the code you’ll find when searching the web. It uses the Registration plugin’s hook gform_user_registered. This comes from the file class-gf-user-registration.php and is called at the end of the create_user() function. We’ll use the normal WordPress function wp_signon to get the job done.

The code would look something like this:

function my_gravity_registration_autologin($user_id, $user_config, $entry, $password) {
  $user     = get_userdata($user_id);
  $login    = $user->user_login;
  $password = $password;
  wp_signon(['user_login' => $login, 'user_password' => $password, 'remember' => true]);
}
add_action('gform_user_registered', 'my_gravity_registration_autologin', 10, 4);

This should work in situations where you use email validation after registration. If the user has to activate via email and then set their password, then the $password variable will have something in it. But if you have immediate activation turned off, $password will be empty! This means your auto-login will fail.

Email activation is turned off in Gravity Forms Registration settings.

What you should do is add a little sanity check to see if the login actually worked. Change the code to this:

function my_gravity_registration_autologin($user_id, $user_config, $entry, $password) {
  $user = get_userdata($user_id);
  if ($user) {
    $login    = $user->user_login;
    $password = $password;
    $status   = wp_signon([
      'user_login'    => $login,
      'user_password' => $password,
      'remember'      => true
    ]);
    if (is_wp_error($status)) {
      error_log("Auto-login failed for user: " . print_r($status,true));
    }
  }
}
add_action('gform_user_registered', 'my_gravity_registration_autologin', 10, 4);

Now you can at least get an error log message if something doesn’t work, and if you aren’t using email activation, you should indeed get a log message about the password field being blank.

Login by setting the auth cookie

So how do we fix this? The $user_config and the $entry both don’t have the plain text password shown. And the wp_signon() function requires a plaintext password to attempt the login.

Some have tried to solve this by manually logging in the user via other functions. That code would look like this:

function my_gravity_registration_autologin($user_id, $user_config, $entry, $password) {
  $user = get_userdata($user_id);
  if ($user) {
    wp_clear_auth_cookie();
    $setuser = wp_set_current_user($user_id);
    wp_set_auth_cookie($user_id);
    do_action('wp_login', $user->user_login, $user);
  }
}
add_action('gform_user_registered', 'my_gravity_registration_autologin', 10, 4);

To automatically login a user via code, there are three steps:

  1. Clear any auth cookie that might already exist. This will log out a current user. You may wish to have different logic about this, for example quit the function if you check and there is already a current user logged in.
  2. Set the auth cookie with wp_set_auth_cookie(). This does not require user credentials checking, it only requires that you pick a valid user ID.
  3. After setting the authentication cookie, it’s a good idea to “inform” the rest of the codebase that a user just logged in, by triggering the wp_login hook. This ensures other plugins and code can do their thing after a new user authenticates.

The caveat with this code is that you cannot set a cookie if headers are already sent to the browser. Some hooks may be too late in the bootstrap to be able to do this. In my experience, using the gform_user_registered hook did not let me set the cookie, it simply didn’t do anything, it didn’t authenticate them or set the cookie at all. The most likely cause was that headers were already sent, but I couldn’t find out how/where at the time. Maybe it would work for you? It might be some other part of my theme or plugin stack that got in the way.

You won’t be able to do this from something like a shortcode handler as this is really late in the bootstrap.

When you set the current user, all you’re doing is setting the global variables to this user ID and details, it’s not actually “logging them in” in the normal sense. If you clear cookies, set cookies, and set the user, then they would be considered logged in.

If you also found that the cookie couldn’t be set from this hook, we move on to the next technique.

Login via Gravity Forms own submission hook

This is quite easy and why didn’t we think of it before? If we need the plaintext password, just hook to Gravity Forms itself instead of the Registration addon’s hook! We’ll use a specific hook that only connects to the registration form I built, which will be gform_after_submission_9999. This hook runs (probably) last of almost all Gravity hooks (and its addons). It only runs when the form was successful, didn’t have validation errors, and passed the honeypot check.

I tested to make sure this hook runs after gform_user_registered and it does. All we need to do is make sure our new user is indeed a user in the DB, which means the registration worked. The code looks like this:

function my_gravity_registration_autologin($entry, $form) {
  // Use the correct ID that contains the email field
  $user = get_user_by('email', $entry[9999]);
  if (!$user) {
    // If there is no user in the DB, the registration didn't actually work
    return;
  }
  // Use the correct ID for the password field, it will be plaintext
  $login = wp_signon([
    'user_login'    => $user->user_login,
    'user_password' => $entry[5555],
    'remember'      => true
  ]);
  if (is_wp_error($login)) {
    error_log("Auto-login failed for user: " . print_r($user,true));
  }
  wp_set_current_user($user->ID);
  }
}
// You may want to increase priority depending on other plugins/code that might be hooking here.
// Use the correct ID for your registration form.
add_action('gform_after_submission_9999', 'my_gravity_registration_autologin', 99, 2);

Here we are using the wp_signon() function because Gravity gives us the password in plain text from the form fields data in the $entry array. Please don’t log this password or try to save it or cache it to do anything else with it for the sake of security. Once WordPress creates the user and hashes the password, you’ll never be able to get it in plain text form again, at least not from Gravity.

We are still using the wp_set_current_user() function because it’s possible other hooks and filters and actions and code, etc, may require access to the current logged in user. This functions makes sure the new user takes over all those global variables. Simply authenticating them and setting the cookie does not do this.

And now your user should be automatically logged in!

Some auto-login caveats

You might want to adjust the code to make sure a user is not already logged in. This could happen for various reasons, such as other tools hooked into the system that logs them in or who knows what. If people can reach your registration page even when already logged in, then they might try to register and this would force the new user to become logged in, bumping out the person who is already logged in. You definitely might not want that depending on your use case.

To check this, use the function get_current_user_id(), it will return 0 if no user is logged in, otherwise it will have a positive integer of the user’s ID.

This code and hook will run even if you disable the Registration addon completely, it’s not needed for this to work. All that’s needed is that the email in the form submission, somehow becomes a valid user in the database before your code runs. The email and password must belong to a real user. If you have some other technique to make that happen, just be sure it runs first.

As a general rule, whenever I have to manually log someone in via code, I like to refresh the page or do a redirect or something because this is really the best way to make sure the entire system is fully aware of the new user and everything bootstraps accordingly. This can be tricky if you are logging them in via ajax calls or REST calls. I would recommend figuring out a way to refresh the page after the login is successful. You can do this in Javascript by setting the location header, or something like window.location.replace(someURL).

I hope that helped!