We've had our authentication code for a while now, but we need to make a little change in our app/Http/Controllers/Auth/LoginController.php
class.
--- a/app/Http/Controllers/Auth/LoginController.php
+++ b/app/Http/Controllers/Auth/LoginController.php
@@ -7,17 +7,6 @@ use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
- /*
- |--------------------------------------------------------------------------
- | Login Controller
- |--------------------------------------------------------------------------
- |
- | This controller handles authenticating users for the application and
- | redirecting them to your home screen. The controller uses a trait
- | to conveniently provide its functionality to your applications.
- |
- */
-
use AuthenticatesUsers;
/**
@@ -25,7 +14,7 @@ class LoginController extends Controller
*
* @var string
*/
- protected $redirectTo = '/home';
+ protected $redirectTo = '/services';
Here we are telling Laravel where to redirect a user after they have logged in. In this case, we are specifying the /services
route we created in the previous episode. We also removed some comments we won't be needing.
We already have a route to show the login page within routes/web.php
. Now it’s time to start using the controllers we have inside the app\Http\Controllers\Auth
folder. For now, we will only activate the routes to login and logout a user. If you have any experience with Laravel, you know this can be achieved by simply adding Auth::routes()
in your routes file. This registers a few other routes we don’t need at the moment like for registration, password resets, etc. In our case, we will register the routes we want manually. We can do this as follows:
--- a/routes/web.php
+++ b/routes/web.php
<?php
-Route::get('/login', function () {
- return view('login');
-})->name('login');
+/*
+|--------------------------------------------------------------------------
+| Authentication
+|--------------------------------------------------------------------------
+|
+*/
+
+Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login');
+Route::post('/login', 'Auth\LoginController@login');
+Route::get('/logout', 'Auth\LoginController@logout')->name('logout');
At the moment, we are specifying within the class constructor that before any user can access anything provided by this class, they must be authenticated. There is nothing wrong with doing it this way, but many developers might argue that it’s better to prevent the request from even getting to the controller class. We should add validation to the route so that it verifies that the user is authenticated even before sending the request through to the controller class. First, we can remove the constructor from our ServicesController class, since we’ll be adding the middleware from our routes/web.php
file. Then we can update our routes file as follows:
--- a/app/Http/Controllers/ServicesController.php
+++ b/app/Http/Controllers/ServicesController.php
@@ -7,11 +7,6 @@ use Illuminate\Support\Facades\Auth;
class ServicesController extends Controller
{
- public function __construct()
- {
- $this->middleware('auth');
- }
-
public function index()
{
$services = Service::byUser(Auth::user())->get();
--- a/routes/web.php
+++ b/routes/web.php
-Route::get('/services', 'ServicesController@index')->name('services');
+/*
+|--------------------------------------------------------------------------
+| Application routes
+|--------------------------------------------------------------------------
+|
+| The following routes are application routes. That means an authentication
+| is absolutely necessary to access these on your browser.
+|
+*/
+
+Route::middleware(['auth'])->group(function () {
+ Route::get('/services', 'ServicesController@index')->name('services');
+});
Here we are creating a group of routes. Every route inside here will have the auth
middleware applied.
We haven’t been using layouts to separate our HTML efficiently. We will create our first layout file now. Inside resources/views/layouts/
let’s create a file called skeleton.blade.php
here we’ll add all the HTML that will be shared in our files.
--- /dev/null
+++ b/resources/views/layouts/skeleton.blade.php
@@ -0,0 +1,17 @@
+<!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">
+ <meta name="csrf-token" content="{{ csrf_token() }}">
+
+ <title>@yield('pageTitle', 'PingPing')</title>
+
+ <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet">
+ <link href="{{ mix('/css/app.css') }}" rel="stylesheet">
+</head>
+<body class="@yield('bodyClasses')">
+ @yield('body')
+</body>
+</html>
Let’s modify the resources/views/login.blade.php
file to use the layout file we just created and we'll move it to a folder called auth
. This is fairly simple, we just remove all the HTML that we pulled over to the layout. We’ll need to extend the layout and create a body
section so it will be placed in the @yield
portion of the layout.
On the episode "#003 - We build a login using TailwindCSS" we built our login form. Or at least a basic version of it. We need to modify our form also so that it submits to the login route we registered a while ago and sends the correct payload. Don't forget, to move the file from resources/views/login.blade.php
to resources/views/auth/login.blade.php
as you can see in the diff below.
--- a/resources/views/login.blade.php
+++ b/resources/views/auth/login.blade.php
@@ -1,19 +1,10 @@
-<!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">
- <meta name="csrf-token" content="{{ csrf_token() }}">
+@extends('layouts.skeleton')
- <title>Login</title>
+@section('pageTitle', 'PingPing - Login')
+@section('bodyClasses', 'bg-grey-lighter text-base text-grey-darkest font-normal relative')
- <link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet">
- <link href="{{ mix('/css/app.css') }}" rel="stylesheet">
-</head>
-<body class="bg-grey-lighter text-base text-grey-darkest font-normal relative">
+@section('body')
<div class="h-2 bg-primary"></div>
-
<div class="container mx-auto p-8">
<div class="mx-auto max-w-sm">
<div class="py-10 text-center">
@@ -25,17 +16,23 @@
Welcome back!
</div>
- <form class="bg-grey-lightest px-10 py-10">
+ <form action="/login" method="post" class="bg-grey-lightest px-10 py-10">
{{ csrf_field() }}
<div class="mb-3">
- <input class="border w-full p-3" name="email" type="text" placeholder="E-Mail">
+ <input class="border {{ $errors->first('email') ? 'border-red' : '' }} w-full p-3" name="email" type="text" placeholder="E-Mail">
+ @if ($errors->first('email'))
+ <p class="text-red text-sm mt-1">{{ $errors->first('email') }}</p>
+ @endif
</div>
<div class="mb-6">
- <input class="border w-full p-3" name="password" type="password" placeholder="**************">
+ <input class="border {{ $errors->first('password') ? 'border-red' : '' }} w-full p-3" name="password" type="password" placeholder="**************">
+ @if ($errors->first('password'))
+ <p class="text-red text-sm mt-1">{{ $errors->first('password') }}</p>
+ @endif
</div>
<div class="flex">
- <button class="bg-primary hover:bg-primary-dark w-full p-4 text-sm text-white uppercase font-bold tracking-wider">
+ <button type="submit" class="bg-primary hover:bg-primary-dark w-full p-4 text-sm text-white uppercase font-bold tracking-wider">
Login
</button>
</div>
@@ -50,5 +47,4 @@
</div>
</div>
</div>
-</body>
-</html>
+@stop
Here we are doing quite a few things. We updated the action attribute on the form and set the method attribute to post
. We are doing some checks for validation errors to apply different styles on the inputs and we are displaying the errors sent back from the server. We also added a type attribute equal to submit on our button.
Last but not least, we need to create a new color in our tailwind.js
file. In this file, we can configure every little part of Tailwind. Here we’ll simply add a new color attribute to our colors object.
--- a/tailwind.js
+++ b/tailwind.js
@@ -57,7 +57,9 @@ let colors = {
'white': '#ffffff',
'primary': '#2b79c1',
- 'primary-dark': '#266299'
+ 'primary-dark': '#266299',
+
+ 'red': '#bf6464',
}
You need to compile your assets again so that Tailwind generates our newly added color.
We did only a few things, but they were very important. Thanks for following the progress on building PingPing, hopefully, you are enjoying these posts.