0

I'm developing a custom module that should register and login users without use the native Drupal login/register form. The problem is that when I create an user in Drupal gestor, and try log it in, the session is created and user redirected to the administrative pages; when I create a user through my registration form (the user is created in the database and showed correctly in drupal gestor) and try to log it in, the user is redirected to the administrative pages (permissions and password were correctly validated) but the session is not created. As I see, this only happens with programmatically created accounts. If I try to log in an gestor created account, with my script, the session is created correctly.

The registration code is the following.

    $userData = \Drupal::service('user.data');
    $passI = \Drupal::service('password');
    $user_data = array(
        'name' => $form_state->getValue('nombres'),
        'mail' => $form_state->getValue('correo'),
        'pass' => $form_state->getValue('contrasena'),
        'init' => $form_state->getValue('correo'),
        'status' => 1,
        'timezone' => 'America/Bogota',
        'roles' => array('usuario_base','authenticated'),
    );
    $user = User::create($user_data);
    $user->save();

    $userData->set('my_module', $user->uid->value, 'apellidos', $form_state->getValue('apellidos'));
    $userData->set('my_module', $user->uid->value, 'pais', $form_state->getValue('pais'));
    $userData->set('my_module', $user->uid->value, 'ciudad', $form_state->getValue('ciudad'));

    $company_data = array(
        'estado' => true,
        'razon_social' => $form_state->getValue('razon_social'),
        'nit' => $form_state->getValue('nit'),
        'resumen' => "",
        'tipo' => $form_state->getValue('tipo'),
        'producto' => $form_state->getValue('producto'),
        'responsable' => $user->uid->value,
    );
    $company = Company::create($company_data);
    $company->save();

    $userData->set('my_module', $user->uid->value, 'empresa', $company->id->value);

    if (!is_null($user) && !is_null($company)) {
        $userr = User::load($user->uid->value);
        user_login_finalize($userr);
        $this->my_module_sso_user_login($userr);
    } else {
        $response = new RedirectResponse("registro");
        $response->send();
        $this->messenger->addWarning('Datos incorrectos', MessengerInterface::TYPE_WARNING);
    }

The login code is the following.

public function submitForm(array &$form, FormStateInterface $form_state) {

    parent::submitForm($form, $form_state);

    $usuario = $form_state->getValue('usuario');
    $contrasena = $form_state->getValue('contrasena');

    $users = \Drupal::entityTypeManager()->getStorage('user')
        ->loadByProperties(['mail' => $usuario]);
    $user_get = reset($users);

    $roles_admitidos = array('administrator','base_user');
    $passI = \Drupal::service('password');

    if($this->hasPermission($user_get->getRoles(true),$roles_admitidos) || $user_get->id() == 1){
        if ($passI->check($contrasena, $user_get->pass->value)) {
            $user = User::load($user_get->uid->value);
            user_login_finalize($user);
            $this->my_module_user_login($user);
        } else {
            $response = new RedirectResponse("/colaborador/failed");
            $response->send();
        }
    } else {
        $response = new RedirectResponse("/colaborador/denied");
        $response->send();
    }
}

public function my_module_user_login($account)
{
    $response = new RedirectResponse("/admin/my_module");
    $response->send();
    return;
}

public function hasPermission($roles,$roles_admitidos)
{
    foreach ($roles as $rol){
        if(in_array($rol,$roles_admitidos)){
            return true;
        }
    }
    return false;
}

The error I get is the following.

RuntimeException: Failed to start the session because headers have already been sent by "/home/xxxx/public_html/xxxx/vendor/symfony/http-foundation/Response.php" at line 1286. in /home/xxxx/public_html/xxxx/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php on line 141 #0 /home/xxxx/public_html/xxxx/core/lib/Drupal/Core/Session/SessionManager.php(164): Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage->start()

I don't know why are the headers sent only when the user is programmatically created.

  • 1
    hook_user_login will be called when a user is logging in automatically, there is no need for you to call your my_module_user_login directly, this will already happen. I would first advise naming the functions something different, unless it is intended to be an implementation of hook_user_login. – Kevin Mar 6 at 15:43
  • 1
    I am not 100% sure RedirectResponse is needed in a form submit either, over $form_state->setRedirect(). I don't know the entire use case here, but you could also have implemented your own UserAuth service to streamline this, instead of ad-hoc forms. – Kevin Mar 6 at 15:48
  • I don't know how make custom UserAuth, you know some guide or tutorial for this? please. Disablen the hook_user_login still equal. only login drupal created users. – Jjsg08 Mar 6 at 17:11
  • Not sure but maybe it could help drupal.stackexchange.com/questions/250597/… – Sébastien Gicquel Jul 17 at 14:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.