Thứ Tư, 12 tháng 10, 2016

laravel 5 tutorial : User Authentication with Ajax Validation in laravel 5.3


Laravel 5.3 tutorial - Working with Ajax, we can create User Authentication with Ajax Validation, At the previews tutorial, we have learn how to crate User authentication in laravel 5.3, please read for more detail here.

How to add Ajax form validation to Laravel User Authentication that is generated by the Artisan console.

User Authentication with Ajax Validation

First step, we will create new database named with "authentication_db" or anything you want, and next crate new Laravel project using composer, please read How to Install laravel.

User Authentication with Ajax Validation in laravel 5.3

Create Laravel Project

cd c:\xampp\htdocs
......
composer create-project --prefer-dist laravel/laravel hckr

"hckr" is our project name, you change it with another name.

After finished, open your project with Text Editor (i'm using Atom Tex Editor).

Create Connection

Configuration our project to connect to database, Open your .ENV file and configuration with yours.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=hckr_db
DB_USERNAME=root
DB_PASSWORD=yourpassword

Generate Authentication

Create default authentication from laravel following by this Artisan Comamand.

php artisan make:auth

Now the Laravel site has routes and views to allow a user to register, login, logout, and reset their password. A HomeController has also been added to allow authenticated users to enter its view.

Database Migration

To migrate our "users" table run migration following by this command

php artisan migrate

User Model

Next create a folder named with "Models" in the app directory and then move the User.php model into app/Models/.
or you can run this command

mkdir app/Models
....
mv app/User.php app/Models

Next, we need to update the App namespace to App\Models. And adding the public function rules() to the class.

<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
    use Notifiable;
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];
    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
    public function rules(){
      return [
        'name' => 'required|max:255',
        'email' => 'required|email|max:255|unique:users',
        'password' => 'required|min:6|confirmed',
      ];
    }
}

Registration Controller

Locate the validator function and replace the array of rules being passed to the Validator make method with a call to the newly created rules method in our User model.

<?php

namespace App\Http\Controllers\Auth;

use App\Models\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\Registers\Users;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

    /**
     * Where to redirect users after login / registration.
     *
     * @var string
     */
    protected $redirectTo = '/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest');
    }

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return IlluminateContractsValidationValidator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, (new User)->rules());
    }

    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return User
     */
    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }
}

Config/Auth.php

Edit, config/auth.php, update the authentication drivers user provider.

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => AppModelsUser::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

User Validation Controller

Create a new Validation folder in Controllers following by this command.

mkdir app/Http/Controllers/Validation

Create a new controller: app/Http/Controllers/Validation/UserController.php in the new Validation folder. It has a single method that applies the rules from the User model for validation.

<?php
namespace App\Http\Controllers\Validation;
use App\Models\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests;
class UserController extends Controller
{
   public function user(Request $request){
     $this->validate($request, (new User)->rules());
   }
}

Routes (Routes/web.php)

Create new route into routes/web.php file to register a route group using api middleware. Inside this group add a validate/user route that accepts a POST method. The request is then sent to the new Validation\UserController user method for validation.

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| This file is where you may define all of the routes that are handled
| by your application. Just tell Laravel the URIs it should respond
| to using a Closure or controller method. Build something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Route::group(['middleware' => ['api']], function () {
    Route::post('validate/user',[
      'uses' => 'ValidationUserController@user',
    ]);
});

Auth::routes();

Route::get('/home', 'HomeController@index');

Register Form Template

Edit the user registration form template, That stored on resources/views/auth/register.blade.php. Remove all the blade if statements that surround the span help blocks. Each of these blocks need to be rendered by the server and made available to the javascript to display any errors.

This full source code from register.blade.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Register</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form" method="POST" action="{{ url('/register') }}">
                        {{ csrf_field() }}

                        <div class="form-group{{ $errors->has('name') ? ' has-error' : '' }}">
                            <label for="name" class="col-md-4 control-label">Name</label>

                            <div class="col-md-6">
                                <input id="name" type="text" class="form-control" name="name" value="{{ old('name') }}" required autofocus>

                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                            </div>
                        </div>

                        <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                            <label for="email" class="col-md-4 control-label">E-Mail Address</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required>

                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                            </div>
                        </div>

                        <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
                            <label for="password" class="col-md-4 control-label">Password</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control" name="password" required>

                                    <span class="help-block">
                                        <strong>{{ $errors->first('password') }}</strong>
                                    </span>
                            </div>
                        </div>

                        <div class="form-group{{ $errors->has('password_confirmation') ? ' has-error' : '' }}">
                            <label for="password-confirm" class="col-md-4 control-label">Confirm Password</label>

                            <div class="col-md-6">
                                <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required>

                                    <span class="help-block">
                                        <strong>{{ $errors->first('password_confirmation') }}</strong>
                                    </span>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Register
                                </button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

Layouts/app.blade.php

Edit the base layout template that stored on resources/views/layouts/app.blade.php. Near the top of the file add a meta tag to make the csrf-token available for the JavaScript ajax function and At the bottom of the app.blade base layout file, before the closing body tag, add the JavaScript.

This full source code of app.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Styles -->
    <link href="/css/app.css" rel="stylesheet">

    <!-- Scripts -->
    <script>
        window.Laravel = <?php echo json_encode([
            'csrfToken' => csrf_token(),
        ]); ?>
    </script>
</head>
<body>
    <div id="app">
        <nav class="navbar navbar-default navbar-static-top">
            <div class="container">
                <div class="navbar-header">

                    <!-- Collapsed Hamburger -->
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
                        <span class="sr-only">Toggle Navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>

                    <!-- Branding Image -->
                    <a class="navbar-brand" href="{{ url('/') }}">
                        {{ config('app.name', 'Laravel') }}
                    </a>
                </div>

                <div class="collapse navbar-collapse" id="app-navbar-collapse">
                    <!-- Left Side Of Navbar -->
                    <ul class="nav navbar-nav">
                        &nbsp;
                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="nav navbar-nav navbar-right">
                        <!-- Authentication Links -->
                        @if (Auth::guest())
                            <li><a href="{{ url('/login') }}">Login</a></li>
                            <li><a href="{{ url('/register') }}">Register</a></li>
                        @else
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
                                    {{ Auth::user()->name }} <span class="caret"></span>
                                </a>

                                <ul class="dropdown-menu" role="menu">
                                    <li>
                                        <a href="{{ url('/logout') }}"
                                            onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                            Logout
                                        </a>

                                        <form id="logout-form" action="{{ url('/logout') }}" method="POST" style="display: none;">
                                            {{ csrf_field() }}
                                        </form>
                                    </li>
                                </ul>
                            </li>
                        @endif
                    </ul>
                </div>
            </div>
        </nav>

        @yield('content')
    </div>

    <!-- Scripts -->
    <script src="/js/app.js"></script>

    <script>
    $(function() {

        var app = {
            DOM: {},
            init: function () {

                // only applies to register form
                if (window.location.pathname == '/register') {

                    this.DOM.form = $('form');
                    this.DOM.form.name  = this.DOM.form.find('input[name="name"]');
                    this.DOM.form.email = this.DOM.form.find('input[name="email"]');
                    this.DOM.form.pwd   = this.DOM.form.find('input[name="password"]');
                    this.DOM.form.pwdc  = this.DOM.form.find('input[name="password_confirmation"]');

                    this.DOM.form.name.group = this.DOM.form.name.closest('.form-group');
                    this.DOM.form.email.group = this.DOM.form.email.closest('.form-group');
                    this.DOM.form.pwd.group = this.DOM.form.pwd.closest('.form-group');

                    this.DOM.form.submit( function(e) {
                        e.preventDefault();

                        var self = this; // native form object

                        error = {};

                        app.DOM.form.name.group.find('strong').text('');
                        app.DOM.form.email.group.find('strong').text('');
                        app.DOM.form.pwd.group.find('strong').text('');

                        app.DOM.form.name.group.removeClass('has-error');
                        app.DOM.form.email.group.removeClass('has-error');
                        app.DOM.form.pwd.group.removeClass('has-error');

                        var user = {};
                        user.name = app.DOM.form.name.val();
                        user.email = app.DOM.form.email.val();
                        user.password = app.DOM.form.pwd.val();
                        user.password_confirmation = app.DOM.form.pwdc.val();

                        var request = $.ajax({
                            headers: {
                                'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
                            },
                            url: '/validate/user',
                            type: 'POST',
                            contentType: 'application/json',
                            data: JSON.stringify(user)
                        });
                        request.done( function(data)
                        {
                            // native form submit
                            self.submit();
                        });
                        request.fail( function(jqXHR)
                        {
                            error = jqXHR.responseJSON;
                            if (error.name) {
                                app.DOM.form.name.group.find('strong').text(error.name[0]);
                                app.DOM.form.name.group.addClass('has-error');
                            }
                            if (error.email) {
                                app.DOM.form.email.group.find('strong').text(error.email[0]);
                                app.DOM.form.email.group.addClass('has-error');
                            }
                            if (error.password) {
                                app.DOM.form.pwd.group.find('strong').text(error.password[0]);
                                app.DOM.form.pwd.group.addClass('has-error');
                            }

                        });

                    });
                }
            }
        }
        app.init();
    });
    </script>
</body>
</html>

Video tutorial User Authentication with Ajax Validation in laravel 5.3



Download User Authentication with Ajax Validation in laravel 5.3

See you next lessons....

Không có nhận xét nào:

Đăng nhận xét