composer create-project laravel/laravel:^9.0 laravel_login_register_v4
cd laravel_login_register_v4
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_db_name
DB_USERNAME=your_db_username
DB_PASSWORD=your_db_password
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name')->nullable();
$table->string('email')->unique();
$table->string('username')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
app/Models/User.php
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
'email',
'username',
'password',
];
/**
* Always encrypt the password when it is updated.
*
* @param $value
* @return string
*/
public function setPasswordAttribute($value)
{
$this->attributes['password'] = bcrypt($value);
}
php artisan make:controller RegisterController
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use App\Http\Requests\RegisterRequest;
class RegisterController extends Controller
{
/**
* Display register page.
*
* @return \Illuminate\Http\Response
*/
public function show()
{
return view('auth.register');
}
/**
* Handle account registration request
*
* @param RegisterRequest $request
*
* @return \Illuminate\Http\Response
*/
public function register(RegisterRequest $request)
{
$user = User::create($request->validated());
auth()->login($user);
return redirect('/')->with('success', "Account successfully registered.");
}
}
php artisan make:request RegisterRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'email' => 'required|email:rfc,dns|unique:users,email',
'username' => 'required|unique:users,username',
'password' => 'required|min:8',
'password_confirmation' => 'required|same:password'
];
}
}
php artisan make:controller LoginController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests\LoginRequest;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/**
* Display login page.
*
* @return Renderable
*/
public function show()
{
return view('auth.login');
}
/**
* Handle account login request
*
* @param LoginRequest $request
*
* @return \Illuminate\Http\Response
*/
public function login(LoginRequest $request)
{
$credentials = $request->getCredentials();
if(!Auth::validate($credentials)):
return redirect()->to('login')
->withErrors(trans('auth.failed'));
endif;
$user = Auth::getProvider()->retrieveByCredentials($credentials);
Auth::login($user);
return $this->authenticated($request, $user);
}
/**
* Handle response after user authenticated
*
* @param Request $request
* @param Auth $user
*
* @return \Illuminate\Http\Response
*/
protected function authenticated(Request $request, $user)
{
return redirect()->intended();
}
}
php artisan make:request LoginRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;
class LoginRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'username' => 'required',
'password' => 'required'
];
}
/**
* Get the needed authorization credentials from the request.
*
* @return array
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function getCredentials()
{
// The form field for providing username or password
// have name of "username", however, in order to support
// logging users in with both (username and email)
// we have to check if user has entered one or another
$username = $this->get('username');
if ($this->isEmail($username)) {
return [
'email' => $username,
'password' => $this->get('password')
];
}
return $this->only('username', 'password');
}
/**
* Validate if provided parameter is valid email.
*
* @param $param
* @return bool
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
private function isEmail($param)
{
$factory = $this->container->make(ValidationFactory::class);
return ! $factory->make(
['username' => $param],
['username' => 'email']
)->fails();
}
}
php artisan make:controller LogoutController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
class LogoutController extends Controller
{
/**
* Log out account user.
*
* @return \Illuminate\Routing\Redirector
*/
public function perform()
{
Session::flush();
Auth::logout();
return redirect('login');
}
}
php artisan make:controller HomeController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class HomeController extends Controller
{
public function index()
{
return view('home.index');
}
}
<?php
use App\Http\Controllers\HomeController;
use App\Http\Controllers\LoginController;
use App\Http\Controllers\LogoutController;
use App\Http\Controllers\RegisterController;
use Illuminate\Support\Facades\Route;
Route::group(['middleware' => ['guest']], function () {
/**
* Register Routes
*/
Route::get('/register', [RegisterController::class, 'show'])->name('register.show');
Route::post('/register/perform', [RegisterController::class, 'register'])->name('register.perform');
/**
* Login Routes
*/
Route::get('/login', [LoginController::class, 'show'])->name('login.show');
Route::post('/login', [LoginController::class, 'login'])->name('login.perform');
});
Route::group(['middleware' => ['auth']], function () {
Route::get('/soon', [HomeController::class, 'index'])->name('soon');
Route::get('/', [HomeController::class, 'index'])->name('home.index');
Route::get('/logout', [LogoutController::class, 'perform'])->name('logout.perform');
Route::prefix('home')->group(function () {
});
});
resources/views/
---layouts/auth-master.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="" />
<meta
name="author"
content="Mark Otto, Jacob Thornton, and Bootstrap contributors"
/>
<meta name="generator" content="Hugo 0.87.0" />
<title>Signin Template · Bootstrap v5.1</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor"
crossorigin="anonymous"
/>
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="signin.css" rel="stylesheet" />
</head>
<body class="text-center d-flex align-items-center justify-content-center vh-100">
<div class="col-3">
<main class="form-signin">
@yield('content')
</main>
</div>
</body>
</html>
resources/views/
---layouts/app-master.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="description" content="" />
<meta
name="author"
content="Mark Otto, Jacob Thornton, and Bootstrap contributors"
/>
<meta name="generator" content="Hugo 0.87.0" />
<title>Fixed top navbar example · Bootstrap v5.1</title>
<link
href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor"
crossorigin="anonymous"
/>
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
</head>
<body>
@include('layouts.partials.navbar')
<main class="container">@yield('content')</main>
<script src="{!! url('assets/bootstrap/js/bootstrap.bundle.min.js') !!}"></script>
</body>
</html>
resources/views/
---layouts/partials/navbar.blade.php
<header class="p-3 bg-dark text-white">
<div class="container">
<div
class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start"
>
<a
href="/"
class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none"
>
<svg
class="bi me-2"
width="40"
height="32"
role="img"
aria-label="Bootstrap"
>
<use xlink:href="#bootstrap" />
</svg>
</a>
<ul
class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0"
>
<li>
<a href="#" class="nav-link px-2 text-secondary">Home</a>
</li>
<li>
<a href="#" class="nav-link px-2 text-white">Features</a>
</li>
<li>
<a href="#" class="nav-link px-2 text-white">Pricing</a>
</li>
<li><a href="#" class="nav-link px-2 text-white">FAQs</a></li>
<li><a href="#" class="nav-link px-2 text-white">About</a></li>
</ul>
<form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3">
<input
type="search"
class="form-control form-control-dark"
placeholder="Search..."
aria-label="Search"
/>
</form>
@auth {{ auth()->user()->name }}
<div class="text-end">
<a
href="{{ route('logout.perform') }}"
class="btn btn-outline-light me-2"
>Logout</a
>
</div>
@endauth @guest
<div class="text-end">
<a
href="{{ route('login.perform') }}"
class="btn btn-outline-light me-2"
>Login</a
>
<a
href="{{ route('register.perform') }}"
class="btn btn-warning"
>Sign-up</a
>
</div>
@endguest
</div>
</div>
</header>
resources/views/
---layouts/partials/messages.blade.php
@if (isset($errors) && count($errors) > 0)
<div class="alert alert-warning" role="alert">
<ul class="list-unstyled mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif @if (Session::get('success', false))
<?php $data = Session::get('success'); ?>
@if (is_array($data)) @foreach ($data as $msg)
<div class="alert alert-warning" role="alert">
<i class="fa fa-check"></i>
{{ $msg }}
</div>
@endforeach @else
<div class="alert alert-warning" role="alert">
<i class="fa fa-check"></i>
{{ $data }}
</div>
@endif @endif
resources/views/
---auth/register.blade.php
@extends('layouts.auth-master') @section('content')
<form method="post" action="{{ route('register.perform') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
<img
class="mb-4"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Bootstrap_logo.svg/1280px-Bootstrap_logo.svg.png"
alt=""
width="72"
height="57"
/>
<h1 class="h3 mb-3 fw-normal">Register</h1>
<div class="form-group form-floating mb-3">
<input
type="email"
class="form-control"
name="email"
value="{{ old('email') }}"
placeholder="name@example.com"
required="required"
autofocus
/>
<label for="floatingEmail">Email address</label>
@if ($errors->has('email'))
<span class="text-danger text-left">{{ $errors->first('email') }}</span>
@endif
</div>
<div class="form-group form-floating mb-3">
<input
type="text"
class="form-control"
name="username"
value="{{ old('username') }}"
placeholder="Username"
required="required"
autofocus
/>
<label for="floatingName">Username</label>
@if ($errors->has('username'))
<span class="text-danger text-left"
>{{ $errors->first('username') }}</span
>
@endif
</div>
<div class="form-group form-floating mb-3">
<input
type="password"
class="form-control"
name="password"
value="{{ old('password') }}"
placeholder="Password"
required="required"
/>
<label for="floatingPassword">Password</label>
@if ($errors->has('password'))
<span class="text-danger text-left"
>{{ $errors->first('password') }}</span
>
@endif
</div>
<div class="form-group form-floating mb-3">
<input
type="password"
class="form-control"
name="password_confirmation"
value="{{ old('password_confirmation') }}"
placeholder="Confirm Password"
required="required"
/>
<label for="floatingConfirmPassword">Confirm Password</label>
@if ($errors->has('password_confirmation'))
<span class="text-danger text-left"
>{{ $errors->first('password_confirmation') }}</span
>
@endif
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Register</button>
@include('auth.partials.copy')
</form>
@endsection
resources/views/
---auth/login.blade.php
@extends('layouts.auth-master') @section('content')
<form method="post" action="{{ route('login.perform') }}">
<input type="hidden" name="_token" value="{{ csrf_token() }}" />
<img
class="mb-4"
src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b2/Bootstrap_logo.svg/1280px-Bootstrap_logo.svg.png"
alt=""
width="72"
height="57"
/>
<h1 class="h3 mb-3 fw-normal">Login</h1>
@include('layouts.partials.messages')
<div class="form-group form-floating mb-3">
<input
type="text"
class="form-control"
name="username"
value="{{ old('username') }}"
placeholder="Username"
required="required"
autofocus
/>
<label for="floatingName">Email or Username</label>
@if ($errors->has('username'))
<span class="text-danger text-left"
>{{ $errors->first('username') }}</span
>
@endif
</div>
<div class="form-group form-floating mb-3">
<input
type="password"
class="form-control"
name="password"
value="{{ old('password') }}"
placeholder="Password"
required="required"
/>
<label for="floatingPassword">Password</label>
@if ($errors->has('password'))
<span class="text-danger text-left"
>{{ $errors->first('password') }}</span
>
@endif
</div>
<button class="w-100 btn btn-lg btn-primary" type="submit">Login</button>
@include('auth.partials.copy')
</form>
@endsection
resources/views/
---auth/partials/copy.blade.php
<p class="mt-5 mb-3 text-muted">© {{ date('Y') }}</p>
resources/views/home/index.blade.php
@extends('layouts.app-master') @section('content')
<div class="bg-light p-5 rounded">
@auth
<h1>Dashboard</h1>
<p class="lead">Only authenticated users can access this section.</p>
<a
class="btn btn-lg btn-primary"
href="https://codeanddeploy.com"
role="button"
>View more tutorials here »</a
>
@endauth @guest
<h1>Homepage</h1>
<p class="lead">
Your viewing the home page. Please login to view the restricted data.
</p>
@endguest
</div>
@endsection
App\Providers\RouteServiceProvider.php
public const HOME = '/home';
public const HOME = '/';
App\Http\Middleware\Authenticate
<?php
namespace App\Http\Middleware;
class Authenticate extends Middleware
{
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
return route('login.show');
}
}
}
php artisan serve
http://127.0.0.1:8000/
http://127.0.0.1:8000/login
http://127.0.0.1:8000/register
Copyright 2023 M. Fadli Zein