Laravel User Registration Validation

May 2020 | John Binzak
1850
Learn how to validate a user in a registration flow from scratch in Laravel.

Overview

The next step of our Laravel Build a Blog tutorial, we will we will validate the input args, create a new user, and display a success message.

Request Helper

Retrieving and validating request input is a common task so let's make a util function to help with such. Let's create app/Http/Models/Util/RequestHelper.php and add the function getArgSafely.


class RequestHelper
{

    public static function getArgSafely(Request $request, $key, $default = null, $sanitize = null){
        $return = $request->has($key) ? $request->input($key) : $default;

        if($return == $default){
            $data = json_decode(file_get_contents('php://input'), true);
            if(is_array($data)) $return = key_exists($key, $data) ? $data[$key] : $return;
        }

        if(!empty($sanitize)){
            return filter_var($return, $sanitize);
        }

        return $return;
    }
}

In this function we will safely check for the request arg and sanitize if need be.

Retrieve Args on Form Submission

Once the user submits the HTML form, we will receive another invocation of the RegisterController index function, expect this time it will be via a POST method. We will add an if block to contain our submission logic to only POST requests. Once we know we have a submission, we will retrieve our args.


    function index(Request $request){

        // set page title
        $this->data['page_title'] = 'Register';

        // post
        if ($request->isMethod('post')) {

            // args
            $email = RequestHelper::getArgSafely($request, 'email');
            $password = RequestHelper::getArgSafely($request, 'password');

        }

        // return view & data
        return view('auth/register', $this->data);
    }

Registration Arg Validation

Before we save to the database, we need to validate the user input. Let's create a static function validateRegistrationArgs in our User.php which will hold our registration logic. As a good practice, we will keep it within our model file opposed to the controller. Within this function we will perform a few basic checks, including a check for existing user records already using that email address, we don't want duplicates! The function will return true if valid, else it will return an error message.


    public static function validateRegistrationArgs($email, $password){

        // valid email
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return 'Invalid email.';
        }

        // existing email
        $item = self::query()->where(['email' => strtolower($email)])->first();
        if(isset($item)){
            return 'Email already being used. Please login.';
        }

        // Validate password length
        $password_length = strlen($password);
        if(empty($password) || $password_length < 8){
            return 'A password must be at least 8 characters.';
        }

        // Validate password type
        if(preg_match('/\s/',$password)){
            return 'A password cannot contain any spaces.';
        }

        // Validate password type
        if(1 !== preg_match('~[0-9]~', $password)){
            return 'A password must contain at least one digit';
        }

        // Validate password type
        if(!preg_match('/[A-Z]/', $password)){
            return 'A password must contain at least one uppercase letter.';
        }

        return true;
    }

Registration Error Display

In our RegisterController, now we will use our User validation function and display the error if need be

Create User

Similar to the validation function, let's create a new static function createNew within our User.php. This will handle setting the model data and saving.


    public static function createNew($email, $password){

        // new item
        $item = new self();
        $item->email = strtolower($email);
        $item->password = password_hash($password, PASSWORD_BCRYPT);
        $item->verification_token = uniqid('CV' . time(), true);
        $item->save();

        return $item;
    }

Registration Success

Now we can save the new user after registration validation. Within our RegistrationController we can invoke the User::createNew function.


    function index(Request $request){

        // set page title
        $this->data['page_title'] = 'Register';

        // post
        if ($request->isMethod('post')) {

            // args
            $email = RequestHelper::getArgSafely($request, 'email', null, FILTER_SANITIZE_EMAIL);
            $password = RequestHelper::getArgSafely($request, 'password');

            // validate
            $validation_result = User::validateRegistrationArgs($email, $password);

            if($validation_result === true){

                // create user
                $user = User::createNew($email, $password);

                // nav to success page
                return redirect('register/success');

            }else{
                // prompt
                $this->data['error_message'] = $validation_result;
            }
        }

        // return view & data
        return view('auth/register', $this->data);
    }

Once we create the user, we will want to navigate the user to a success screen. We will do right after creating a new user.


    function index(Request $request){

        // set page title
        $this->data['page_title'] = 'Register';

        // post
        if ($request->isMethod('post')) {

            // args
            $email = RequestHelper::getArgSafely($request, 'email', null, FILTER_SANITIZE_EMAIL);
            $password = RequestHelper::getArgSafely($request, 'password');

            // validate
            $validation_result = User::validateRegistrationArgs($email, $password);

            if($validation_result === true){

                // create user
                $user = User::createNew($email, $password);

                // nav to success page
                return redirect('register/success');

            }else{
                // prompt
                $this->data['error_message'] = $validation_result;
            }
        }

        // return view & data
        return view('auth/register', $this->data);
    }

For our success view, it will be a simple blade, following the same inheritance pattern as the main registration blade. We also need to create a new route function within RegisterController and add it to the routes file.


    function success(Request $request){

        // set page title
        $this->data['page_title'] = 'Register Success';

        // return view & data
        return view('auth/register_success', $this->data);
    }

// register
Route::get('/register', 'Auth\RegisterController@index');
Route::post('/register', 'Auth\RegisterController@index');
Route::get('/register/success', 'Auth\RegisterController@success');

Summary

Now we have our basic, validated, user registration. This is a simple flow for basic CRUD apps, we can use this example for other form submission features. Next we will verify the user via email. You can find the source code here.

nice
Added from Giphy.