Membuat Sendiri Fitur dan Formulir Registrasi


Laravel sudah menyediakan fitur autentikasi untuk daftar, masuk (login), sampai dengan setel ulang sandi lewat (password). Hanya dengan perintah php artisan make:auth, kita sudah dapat menggunakan semua fitur tersebut tanpa perlu menambahkan skrip satu baris pun.

Walau demikin, beberapa di antara kita bisa jadi lebih suka membuat fitur autentikasi dari awal. Alasannya bisa bermacam-macam, misal: menggunakan tabel yang berbeda dengan bawaan Laravel. Alasan lainya mungkin ada banyak fitur yang ingin ditambahkan pada proses registrasi.

Oh ya, modifikasi fitur registrasi sangat dimungkinkan dan dimudahkan pada Laravel. Salah satu contoh modifikasi pada fitur antentikasi ada pada pos berikut.

Pada dasarnya, membuat fitur registrasi pada Laravel tak ada bedanya dengan menambahkan data baru pada tabel. Yang perlu diperhatikan adalah, ada perlakuan khusus terhadap data sandi lewat yang akan disimpan. Tentunya, sandi lewat harus di-hash sebelum disimpan ke dalam tabel. Selain untuk validasi saat login nanti, hash sandi lewat juga berfungsi untuk keamanan.

Tidak perlu ambil pusing soal hash sandi lewat ini, karena Laravel sudah menyediakan fungsinya dengan nama bcrypt() atau menggunakan facade Hash::make().

Sebagai info, dalam pembuatan fitur registrasi ini kita tetap menggunakan tabel user yang terdapat dalam Laravel. Struktur tabelnya dapat dilihat pada berkas 2014_10_12_000000_create_users_table.php dalam direktori database/migrations.

Membuat Test

Sebagai info, saya menggunakan Laravel Dusk untuk test. Kalian bisa melewati langkah ini jika tidak ingin menggunakan fitur test dalam aplikasi.

Buat test baru dengan nama SignupTest menggunakan Artisan.

$ php artisan dusk:make SignupTest

Berkas SignupTest.php disimpan dalam direktori tests/Browser.

Dalam class test tersebut, akan dibuat dua method untuk melakukan berbagai pengujian. Yaitu:

  1. Ujicoba halaman registrasi (/signup) dapat diakses.
  2. Ujicoba data valid dan proses registrasi berhasil.

Skrip lengkap alur test di atas dapat dilihat di bawah.

<?php

namespace Tests\Browser;

use Tests\DuskTestCase;
use Laravel\Dusk\Browser;
use Illuminate\Foundation\Testing\DatabaseMigrations;

class SignupTest extends DuskTestCase
{
    public function testSignupForm()
    {
        $this->browse(function(Browser $browser) {
            $browser->visit('/signup')
                ->assertSee('Sign Up');
        });
    }

    public function testSignup()
    {
        $this->browse(function(Browser $browser){
            $browser->visit('/signup')
                ->type('name', 'test')
                ->type('email', 'test@email.com')
                ->type('password', 'secretpassword')
                ->type('confirm_password', 'secretpassword')
                ->press('Sign Up')
                ->assertPathIs('/home');
        });
    }
}

Membuat View

Untuk menggunakan template bawaan yang disediakan Laravel, kita harus mengaktifkan fitur autentikasi terlebih dahulu.

$ php artisan auth:make

Dalam direktori resources/views, terdapat berkas baru dengan nama layouts/app.blade.php. Nah, dari fitur autentikasi yang kita generate barusan, hanya template-nya saja yang akan kita gunakan.

Untuk menon-aktifkan fitur autentikasi bawaan Laravel, buka berkas routes/web.php dan hapus bagian skrip di bawah.

Auth::routes();

Jangan lupa untuk mengubah tautan register dan login pada berkas app.blade.php yang terletak dalam direktori resources/views/layouts agar aplikasi tidak terjadi kesalahan. Seperti, route login atau route register tidak ditemukan misalnya.

Buat direktori dan berkas view baru dengan signup/form.blade.php dalam direktori resources/views. Perhtikan penamaan setiap field-nya agar tidak bingung ketika membaca controller untuk proses datanya.

@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">Sign Up</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form" method="POST" action="{{ route('signup.store') }}">
                        {{ csrf_field() }}
                        {{ method_field('post') }}

                        <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') }}" autofocus>

                                @if ($errors->has('name'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('name') }}</strong>
                                    </span>
                                @endif
                            </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="text" class="form-control" name="email" value="{{ old('email') }}">

                                @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                @endif
                            </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">

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

                        <div class="form-group{{ $errors->has('confirm_password') ? ' 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="confirm_password">
                                @if ($errors->has('confirm_password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('confirm_password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

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

Apabila diakses melalui peramban (browser), maka tampilannya akan nampak seperti gambar berikut.

Formulir registrasi

Formulir registrasi

Mendefinisikan Route

Definisikan dua buah route dengan path yang sama, tapi HTTP verb yang berbeda. Seperti disinggung pada sub bagian di atas, kita akan menambahkan route dengan path /signup.

Route::get('signup', 'SignupController@form')->name('signup.form');
Route::post('signup', 'SignupController@signup')->name('signup.store');

Route dengan HTTP verb GET akan menampilkan formulir registrasi, sedangkan route dengan verb POST akan memproses data berupa validasi dan menyimpannya ke dalam tabel users.

Membuat Controller

Berdasarkan definisi route, kita akan membuat satu buah controller dengan nama SignupController. Dalam controller tersebut terdapat dua buah method dengan nama form() dan store(). Method form() berfungsi untuk menampilkan formulir registrasi, sedangkan method store() berfungsi untuk membuat validasi dan menyimpan data user.

<?php

namespace App\Http\Controllers;

use Auth;
use App\User;
use Illuminate\Http\Request;

class SignupController extends Controller
{
    public function form()
    {
        return view('signup.form');
    }

    public function store(Request $request)
    {
        // validate request data
        $this->validate($request, [
            'name' => 'required|string|max:50',
            'email' => 'required|email|max:100|unique:users,email',
            'password' => 'required|min:6',
            'confirm_password' => 'required|same:password'
        ]);

        // save into table
        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => bcrypt($request->password)
        ]);

        // autologin
        Auth::loginUsingId($user->id);

        // redirect to home
        return redirect('/home');
    }
}

Baca juga Tiga Cara Memvalidasi Form di Laravel.

Uji Coba Aplikasi

Ada tiga langkah untuk ujicoba aplikasi:

  1. Menjalankan migration.
  2. Uji coba dengan feature test.
  3. Mencobanya langsung melalui peramban (browser).

Menjalankan Migration

Ubah konfigurasi pangkalan data (database) pada berkas .env, dan sesuaikan dengan pengaturan pangkalan data di mesin lokal. Jalankan migration untuk membuat tabel user.

$ php artisan migrate

Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated:  2014_10_12_000000_create_users_table
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated:  2014_10_12_100000_create_password_resets_table

Feature Test

Jika langkah test di atas kalian lewati, maka lewati juga langkah ini.

Jalankan PHPUnit melalui terminal dari direktori root dengan perintah berikut.

$ php artisan dusk

Uji Coba Melalui Peramban

Jalankan perintah php artisan serve, kemudian akses tautan localhost:8000/signup. Dari situ, kalian bisa mencoba sendiri fitur yang telah dibuat, apakah sudah sesuai atau masih perlu ada perubahan.

Konklusi

Dengan perubahan sistem autentikasi ini, ada banyak kesalahan yang ada pada aplikasi nantinya. Seperti route login, register, logout, dan setel ulang sandi lewat tidak berfungsi. Kalian bisa menghapusnya jika dirasa cukup mengganggu, atau menggantinya sekalian dengan fitur baru yang dibuat dari awal.

Fitur registrasi di atas juga masih dapat dikembangkan sesuai dengan kebutuhan bisnis. Semisal, pada bagian penyimpanan user, ditambahkan proses pengiriman email ke user tersebut untuk verifikasi alamat email. Tentunya, saya bisa bilang begini karena di tulisan berikutnya, saya akan mengimplementasikan sistem verifikasi email pada fitur registrasi.

Terakhir, selamat mencoba!
Jangan sungkan untuk bertanya. Bagikan juga jika bermanfaat. 😉

***

Tulisan juga dapat dibaca pada Publikasi Medium Laravel Indonesia.

Tak Berkategori

Yugo Purwanto

Pemrogram PHP dan JavaScript yang sedang sibuk mengembangkan aplikasi Glosarium Bahasa Indonesia.

2 comments

Tinggalkan Balasan