Can I set Ion auth to login by username OR Email

2019-06-28 06:11发布

I know I can set ion auth to login by username in the config, I also know I can set it to login by email in the config.

Is there a simple way to set it it to use either automatically?

8条回答
Explosion°爆炸
2楼-- · 2019-06-28 06:32

I recently forked Ion Auth and made the necessary enhancements so that this could be chosen in the configuration. The fork is located here:

https://github.com/zepernick/CodeIgniter-Ion-Auth

I offered up a pull request to get this included in the Ion Auth code base, but it has not been accepted at this time. There was some debate going on about whether it made the code to complex. Please drop them a note and let them know you would like this functionality if it is useful to you.

https://github.com/benedmunds/CodeIgniter-Ion-Auth/pull/746

查看更多
姐就是有狂的资本
3楼-- · 2019-06-28 06:38

Put this on your Controller

if ($this->form_validation->run() !== FALSE) {
    $remember = (bool) $this->input->post('remember');
    $this->ion_auth_model->identity_column = 'username/email';

    if ($this->ion_auth->login($this->input->post('username'), $this->input->post('password'), $remember))
    {
        $this->session->set_flashdata('message', $this->ion_auth->messages());
    }
    redirect('auth/login');
}

Edit ion_auth_model.php. find the function login() and the update the code using the code below.

public function login($identity, $password, $remember=FALSE)
    {
        $this->trigger_events('pre_login');

        if (empty($identity) || empty($password))
        {
            $this->set_error('login_unsuccessful');
            return FALSE;
        }

        $this->trigger_events('extra_where');

        //just add this (starting this line)
        if ($this->identity_column == "username/email")
        {
            $fieldname = explode('/', $this->identity_column);
            $query = $this->db->select($fieldname[0] . ', username, email, id, password, active, last_login')
                          ->where($fieldname[0], $identity)
                          ->limit(1)
                          ->get($this->tables['users']);

            $this->identity_column = $fieldname[0];

            if ($query->num_rows() === 0) {
                $query = $this->db->select($fieldname[1] . ', username, email, id, password, active, last_login')
                          ->where($fieldname[1], $identity)
                          ->limit(1)
                          ->get($this->tables['users']);

                $this->identity_column = $fieldname[1];
            }
        }
        else
        {
            $query = $this->db->select($this->identity_column . ', username, email, id, password, active, last_login')
                          ->where($this->identity_column, $identity)
                          ->limit(1)
                          ->get($this->tables['users']);
        }
        //up to this line   

        if($this->is_time_locked_out($identity))
        {
            //Hash something anyway, just to take up time
            $this->hash_password($password);

            $this->trigger_events('post_login_unsuccessful');
            $this->set_error('login_timeout');

            return FALSE;
        }

        if ($query->num_rows() === 1)
        {
            $user = $query->row();

            $password = $this->hash_password_db($user->id, $password);

            if ($password === TRUE)
            {
                if ($user->active == 0)
                {
                    $this->trigger_events('post_login_unsuccessful');
                    $this->set_error('login_unsuccessful_not_active');

                    return FALSE;
                }

                $this->set_session($user);

                $this->update_last_login($user->id);

                $this->clear_login_attempts($identity);

                if ($remember && $this->config->item('remember_users', 'ion_auth'))
                {
                    $this->remember_user($user->id);
                }

                $this->trigger_events(array('post_login', 'post_login_successful'));
                $this->set_message('login_successful');

                return TRUE;
            }
        }

        //Hash something anyway, just to take up time
        $this->hash_password($password);

        $this->increase_login_attempts($identity);

        $this->trigger_events('post_login_unsuccessful');
        $this->set_error('login_unsuccessful');

        return FALSE;
    }
查看更多
在下西门庆
4楼-- · 2019-06-28 06:43

If by automatic, you mean try one and then the other to see if either gives a valid return:

The login occurs in ion_auth_model line: 899

->where($this->identity_column, $this->db->escape_str($identity))

so you could change this to do an "or" and try both columns. You would need to do this throughout the model because there is more than just the actual login to consider & there's the potential issue of a user having an email that is another user's username (however unlikely)

查看更多
三岁会撩人
5楼-- · 2019-06-28 06:44

I think the easier way would be checking if the $identity var is an email. If it's not an email, then you set the column to 'username'. Something like this:

$check_column = valid_email($identity) ? $this->identity_column : 'username';   
$query = $this->db->select('username, email, id, password, active, last_login')
    ->where($check_column, $this->db->escape_str($identity))
    ->limit(1)
    ->get($this->tables['users']);

In this case, you'll need the email_helper loaded.

Works for me.

查看更多
啃猪蹄的小仙女
6楼-- · 2019-06-28 06:45

You can do this without modifying the core code. Just change the identity column on the fly if a valid email is present. NOTE: ion_auth_model not ion_auth.

public function check_login()
{
    if (!$this->input->is_ajax_request()) {
        exit('No direct script access allowed');
    }
    $this->form_validation->set_rules('username', str_replace(':', '', $this->lang->line('login_identity_label')), 'required');
    $this->form_validation->set_rules('password', str_replace(':', '', $this->lang->line('login_password_label')), 'required');
    if ($this->form_validation->run() == false) {
        $this->form_validation->json_errors();
    }
    $identity = $this->input->post('username');
    if ($this->form_validation->valid_email($identity)) {
        $this->ion_auth_model->identity_column = 'email';
    } else {
        $this->ion_auth_model->identity_column = 'username';
    }
    if ($this->ion_auth->login($identity, $this->input->post('password'), false)) {
        encode_response('success');
    } else {
        encode_response('error', $this->ion_auth->errors());
    }
}
查看更多
倾城 Initia
7楼-- · 2019-06-28 06:52

without having to edit ion_auth_model, you can do something like this:

considering you already have this config:

 $config['identity'] = 'username';

and you have this on your controller:

// log the user in
public function login()
{
...
    if ($this->ion_auth->login($this->input->post('identity'), $this->input->post('password'), $remember))
    {
    //if the login is successful

you can let it to check and then if it's not successful, set the email as identity column and check for it:

// log the user in
public function login()
{
...

    // check for username
    $login = $this->ion_auth->login($this->input->post('identity'), $this->input->post('password'), $remember);
    if(! $login) { // username is not successful
        $this->ion_auth_model->identity_column = 'email';
        // check for email
        $login = $this->ion_auth->login($this->input->post('identity'), $this->input->post('password'), $remember);
    }

    if( $login ) {
         // successful
    } else {
         // both failed
    }

the advantage of this: more compatibility with any new update to ionAuth since you didn't change the core files. the downside of this is that's it's have to double query the database.


Auth controller code modified from: ionAuth Auth Controller Example

Discussions on ionAuth Repo:

查看更多
登录 后发表回答