User registration with CodeIgniter

17,597

Solution 1

I would strongly urge you to think about using another library that already does this very well: TankAuth. TankAuth is easily modifiable and offers email confirmation, very secure password hashing, a solid database schema, and very clean code.

There's no reason to reinvent the wheel, especially when it comes to something that's very hard to get right like user authentication.

EDIT:

For example, here's everything TankAuth provides security-wise that you'd have to code yourself (if you cared about security) - how much time would that take?

Using phpass library for password hashing (instead of unsafe md5).
Counting login attempt for bruteforce preventing (optional). Failed login attempts determined by IP and by username.
Logging last login IP-address and time (optional).
CAPTCHA for registration and repetitive login attempt (optional).
Unactivated accounts and forgotten password requests auto-expire.

Solution 2

To do the check you should have functions in your model that can look up those types of things for you:

class Model{
    function getUserByEmail($email);
    function getUserByUsername($username);
    ...
}        

Then in your controller you can call these methods

...
$result = $model->getUserByEmail($_POST['email']); // You'll need to sanitize your POST
if(count($result) > 0){
    // Sent error about email already existing and flag to not insert/update user
}
...

Solution 3

The easiest solution in CodeIgniter is to use a callback function as one of the rules in your form validation. I've used this method myself to check the username and e-mail.

Here's the docs for it.

Solution 4

You need to create a model for your controller.
Your model would look like this:

class Register_model extends CI_Model {
    function register_user()
    {
        $data['username'] = $this->input->post('username');
        $data['password'] = sha1($this->input->post('password'));
        ... (your other post data) ...
        $this->db->insert('users', $data);
    }
}

In your controller you will call the model this way:

$this->load->model('Register_model');

and the method goes here:

else
{
    $this->Register_model->register_user(); 
    $this->load->view('register_done');
}

If you want to check if the username is available, you simply put SELECT query on the first lines of the register_user() method (function).

Share:
17,597
Josh
Author by

Josh

Updated on August 03, 2022

Comments

  • Josh
    Josh over 1 year

    I'm trying to build a registration system with CodeIgniter. I have a controller called Register with the following code:

    class Register extends CI_Controller {
        public function index()
        {
            $this->load->helper(array('form', 'url'));
            $this->load->library('form_validation');
            $this->form_validation->set_error_delimiters('<span class="error">', '</span>');
            $this->form_validation->set_rules('username', 'username', 'required|min_length[3]|max_length[12]|trim');
            $this->form_validation->set_rules('password', 'password', 'required|min_length[2]|md5');
            $this->form_validation->set_rules('email', 'email', 'required|valid_email|trim');
            $this->form_validation->set_rules('artist', 'artist', 'max_length[32]|trim');
            $this->form_validation->set_rules('captcha', 'CAPTCHA', 'required|trim');
            $this->load->view('header');
            if(!$this->form_validation->run())
            {
                $this->load->view('register_form');
            }
            else
            {
                $this->load->view('register_done');
            }
            $this->load->view('footer');
        }
    }
    

    So far so good. If I go to the register page I get the registration form displayed. If I send the form and it passes the form validation checks, I get the success page, if the form has errors, I get the form back with some error messages.

    Now what I want to do is the database stuff. I have some idea of how I can get the POST values from the registration form into my database, but no clue how I can check if a username or email already exists, and if so, display that error on the registration form. Here's my registration form view:

    <?php $this->load->helper('form'); ?>
    <?php echo form_open('register'); ?>
        <ul id="register">
            <ul>
                <h3>Account information</h3>
                <li>
                    <label for="username">Choose a username</label>
                    <input type="text" name="username" value="<?php echo set_value('username'); ?>" />
                    <span class="desc">The name you'd like to be known by</span>
                    <?php echo form_error('username'); ?>
                </li>
                <li>
                    <label for="password">Pick a password</label>
                    <input type="password" name="password" />
                    <span class="desc">The best passwords are random and more than 6 characters long</span>
                    <?php echo form_error('password'); ?>
                </li>
                <li>
                    <label for="email">Enter your valid email address</label>
                    <input type="text" name="email" value="<?php echo set_value('email'); ?>" />
                    <span class="desc">We'll send you an activation email</span>
                    <?php echo form_error('email'); ?>
                </li>
            </ul>
            <ul>
                <h3>About you</h3>
                <li>
                    <label for="band">Who's your favorite artist?</label>
                    <input type="text" name="artist" value="<?php echo set_value('artist'); ?>" />
                    <span class="desc">Don't put Lady GaGa.</span>
                    <?php echo form_error('artist'); ?>
                </li>
            </ul>
            <ul>
                <h3>Security question</h3>
                <li>
                    <label for="captcha">Enter the letters you see in the image</label>
                    <?php $this->load->helper('captcha');
                    $cap = create_captcha(array('img_path' => './captcha/', 'img_url' => 'http://localhost/captcha/', 'img_width' => 200, 'img_height' => 30));
                    $data = array('captcha_time' => $cap['time'], 'ip_address' => $this->input->ip_address(), 'word' => $cap['word']);
                    $query = $this->db->insert_string('captcha', $data);
                    $this->db->query($query);
                    echo $cap['image']; ?>
                    <input type="text" name="captcha" />
                    <?php echo form_error('captcha'); ?>
                </li>
            </ul>
            <ul>
                <h3 class="submit">
                    <input type="submit" value="Register" />
                </h3>
            </ul>
        </ul>
    <?php echo form_close(); ?>
    

    As you can see, I'm taking advantage of the form_error() function of CI to display form errors right under the field, and I would like the "username already exists" error to also be displayed under the username field.

    Can anyone provide some help? Even a nudge in the right direction?

    Thanks!

    • afuzzyllama
      afuzzyllama almost 13 years
      MD5 is broken, you should look to see if you can get your password encryption to work with SHA1. Also, do you have a model yet for accessing/storing your user information? Lastly, why is your registration code in your index page? It should be in its own function.
    • Josh
      Josh almost 13 years
      No, I don't have a model, but that's probably a good idea. My registration code is in my index method because I access my registration form by going to: http://site.com/register. The registration form is the only thing I want displayed on that page, so I don't see the advantages to making a separate register method.
  • Michael B
    Michael B almost 13 years
    Using SHA-1 alone without a salt is not advised and could be insecure.
  • shaggy
    shaggy almost 13 years
    @Kyle Boddy - so what? Should I write entire code for him? I just showed him the way, it's not complete code.
  • Michael B
    Michael B almost 13 years
    You should not recommend possibly insecure methods without pointing it out. This is the whole reason my answer relies on a third party library that uses PHPass and accounts for many of the issues that crop up when writing your own authentication library.
  • shaggy
    shaggy over 12 years
    sha1 without salt is not insecure. Your library is still just an php code using the same hash algorithm as my code. It is not safer just beacause it's "a magic library and md5 is bad".
  • Farhad
    Farhad almost 11 years
    Last activity was 2 years ago. Isn't old?
  • Siddharth Shukla
    Siddharth Shukla over 7 years
    Controller part User.php
  • Siddharth Shukla
    Siddharth Shukla over 7 years
    User_model.php model part