Laravel Application Development Cookbook
上QQ阅读APP看书,第一时间看更新

Creating an authentication system

In this recipe, we'll be creating a simple authentication system. It can be used as it is or extended to include much more functionality.

Getting ready

We will be using the code created in the Setting up and configuring the Auth library recipe as the basis for our authentication system.

How to do it...

To finish this recipe, follow these steps:

  1. Create a route in our routes.php file to hold our registration form:
    Route::get('registration', function()
    {
        return View::make('registration');
    });
  2. Create a registration form by creating a new file in app/views named as registration.php:
    <!DOCTYPE html>
    <html>
        <head>
            <title>Laravel Authentication - Registration</title>
            <meta charset="utf-8">
        </head>
        <body>
            <h2>Laravel Authentication - Registration</h2>
            <?php $messages =  $errors->all('<p style="color:red">:message</p>') ?>
            <?php foreach ($messages as $msg): ?>
                <?= $msg ?>
            <?php endforeach; ?>
    
    
    <?= Form::open() ?>
            <?= Form::label('email', 'Email address: ') ?>
            <?= Form::text('email', Input::old('email')) ?>
            <br>
            <?= Form::label('password', 'Password: ') ?>
            <?= Form::password('password') ?>
            <br>
            <?= Form::label('password_confirm','Retype Password: ') ?>
            <?= Form::password('password_confirm') ?>
            <br>
            <?= Form::label('name', 'Name: ') ?>
            <?= Form::text('name', Input::old('name')) ?>
            <br>
            <?= Form::label('admin', 'Admin?: ') ?>
            <?= Form::checkbox('admin','true',Input::old('admin')) ?>
            <br>
            <?= Form::submit('Register!') ?>
            <?= Form::close() ?>
        </body>
    </html>
  3. Make a route to process the registration page:
    Route::post('registration', array('before' => 'csrf',function()
    {
        $rules = array(
            'email'    => 'required|email|unique:users',
            'password' => 'required|same:password_confirm',
            'name'     => 'required'
        );
        $validation = Validator::make(Input::all(), $rules);
    
        if ($validation->fails())
        {
            return Redirect::to('registration')->withErrors($validation)->withInput();
        }
    
        $user           = new User;
        $user->email    = Input::get('email');
        $user->password = Hash::make(Input::get('password'));
        $user->name     = Input::get('name');
        $user->admin    = Input::get('admin') ? 1 : 0;
        if ($user->save())
        {
            Auth::loginUsingId($user->id);
            return Redirect::to('profile');
        }
        return Redirect::to('registration')->withInput();
    }));
  4. Make a simple page for your profile by adding a route in routes.php:
    Route::get('profile', function()
    {
        if (Auth::check())
        {
            return 'Welcome! You have been authorized!';
        }
        else
        {
            return 'Please <a href="login">Login</a>';
        }
    });
  5. Create a login route in routes.php to hold the login form:
    Route::get('login', function()
    {
        return View::make('login');
    });
  6. In our app/views directory, create a file named login.php:
    <!DOCTYPE html>
    <html>
        <head>
            <title>Laravel Authentication - Login</title>
            <meta charset="utf-8">
        </head>
        <body>
            <h2>Laravel Authentication - Login</h2>
            <?= '<span style="color:red">' .Session::get('login_error') . '</span>' ?>
    
            <?= Form::open() ?>
            <?= Form::label('email', 'Email address: ') ?>
            <?= Form::text('email', Input::old('email')) ?>
            <br>
            <?= Form::label('password', 'Password: ') ?>
            <?= Form::password('password') ?>
            <br>
            <?= Form::submit('Login!') ?>
            <?= Form::close() ?>
        </body>
    </html>
  7. Create a route in routes.php to authenticate the login:
    Route::post('login', function()
    {
        $user = array(
            'username' => Input::get('email'),
            'password' => Input::get('password')
        );
    
        if (Auth::attempt($user))
        {
            return Redirect::to('profile');
        }
    
        return Redirect::to('login')->with('login_error','Could not log in.');
    });
  8. Create a route in routes.php that is a secured page:
    Route::get('secured', array('before' => 'auth', function()
    {
        return 'This is a secured page!';
    }));

How it works...

To begin with, we create a fairly simple registration system. In our registration form, we'll be asking for an e-mail address, password, password confirmation, a name, and then an option for whether the user is an admin. In the form fields, we also add Input::old(); thus, if the form doesn't validate correctly, we can repopulate the fields without needing the user to re-enter all the information.

Our form then posts, adding in the CSRF filter, and runs through some validation. If the validation passes, we create a new instance of our User model and add in the fields from our form. For the password, we use Hash::make() to keep the password secure. Since our admin field accepts a boolean value, we see if the admin checkbox was checked; if so, we set the value to 1.

If everything is saved correctly, we can automatically log in the user by passing the just created user ID to Auth::loginUsingId(), and redirect them to the profile page.

The first thing the profile route does is run Auth::check() to see if the user is actually logged in. If he/she isn't, it will display a link to the login page.

The login page is a simple form asking for e-mail ID and password. When submitted, we put those two values in an array and pass them to Auth::attempt(), which will automatically hash our password, and look up the credentials in the database. If it's successful, the Auth class will set a session and we redirect the user to the profile page.

If the user happens to try and access the secured routes, the system will direct them to the login page. Using Laravel's Redirect::intended(), we can then direct them back to the page they originally tried to access.

See also

  • The Setting up and configuring the Auth library recipe